diff --git a/WebsitePanel.WHMCSModule/changelog.log b/WebsitePanel.WHMCSModule/changelog.log
new file mode 100644
index 00000000..02488cf6
--- /dev/null
+++ b/WebsitePanel.WHMCSModule/changelog.log
@@ -0,0 +1,3 @@
+01/29/2013 (1.2)
+* WebsitePanel addons no longer require the storage of the Enterprise Server credentials
+* Error codes are not properly resolved to their text responses
\ No newline at end of file
diff --git a/WebsitePanel.WHMCSModule/includes/hooks/websitepanel_addons.php b/WebsitePanel.WHMCSModule/includes/hooks/websitepanel_addons.php
index 5d628e81..52ddeef0 100644
--- a/WebsitePanel.WHMCSModule/includes/hooks/websitepanel_addons.php
+++ b/WebsitePanel.WHMCSModule/includes/hooks/websitepanel_addons.php
@@ -46,15 +46,17 @@ function websitepanel_addons_AddonActivation($params)
{
// Sanity check to make sure the associated service is WebsitePanel based product
// And that the addon purchased has an associated WebsitePanel addon
- $results = full_query("SELECT h.id AS `id` FROM `tblhosting` AS h, `tblwspaddons` AS w, `tblservers` AS s WHERE h.id = {$params['serviceid']} AND h.server = s.id AND s.type = 'websitepanel' AND w.whmcs_id = {$params['addonid']}");
+ $results = full_query("SELECT h.id AS `id` FROM `tblhosting` AS h, `mod_wspaddons` AS w, `tblservers` AS s WHERE h.id = {$params['serviceid']} AND h.server = s.id AND s.type = 'websitepanel' AND w.whmcs_id = {$params['addonid']}");
if (mysql_num_rows($results) > 0)
{
// Include the WebsitePanel ES Class
require_once(ROOTDIR . '/modules/servers/websitepanel/websitepanel.class.php');
+ require_once(ROOTDIR . '/modules/servers/websitepanel/websitepanel.functions.php');
// Retrieve the WebsitePanel Addons module settings
$modSettings = websitepanel_addons_GetSettings();
- if (empty($modSettings['username']) || empty($modSettings['password']) || empty($modSettings['serverhost']) || empty($modSettings['serverport']))
+ $srvSettings = websitepanel_GetServerSettings();
+ if (empty($modSettings['serverhost']) || empty($modSettings['serverport']) || empty($srvSettings['username']) || empty($srvSettings['password']))
{
// The module is disabled or has not yet been configured - stop
return;
@@ -71,7 +73,7 @@ function websitepanel_addons_AddonActivation($params)
}
// Create the WebsitePanel object instance
- $wsp = new WebsitePanel($modSettings['username'], $modSettings['password'], $modSettings['serverhost'], $modSettings['serverport'], (($modSettings['serversecured']) == 'on' ? TRUE : FALSE));
+ $wsp = new WebsitePanel($srvSettings['username'], $srvSettings['password'], $modSettings['serverhost'], $modSettings['serverport'], (($modSettings['serversecured']) == 'on' ? TRUE : FALSE));
// Grab the user's details from WebsitePanel in order to get the user's id
$user = $wsp->get_user_by_username($username);
@@ -89,7 +91,7 @@ function websitepanel_addons_AddonActivation($params)
}
// Get the associated WebsitePanel addon id
- $results = select_query('tblwspaddons', 'wsp_id,is_ipaddress', array('whmcs_id' => $params['addonid']));
+ $results = select_query('mod_wspaddons', 'wsp_id,is_ipaddress', array('whmcs_id' => $params['addonid']));
$addon = mysql_fetch_array($results);
$addonPlanId = $addon['wsp_id'];
$addonIsIpAddress = $addon['is_ipaddress'];
@@ -129,7 +131,7 @@ function websitepanel_addons_GetSettings()
$results = select_query('tbladdonmodules', 'setting,value', array('module' => 'websitepanel_addons'));
while (($row = mysql_fetch_array($results)) != false)
{
- $settings[$row['setting']] = $row['value'];
+ $settings[$row[0]] = $row[1];
}
return $settings;
}
\ No newline at end of file
diff --git a/WebsitePanel.WHMCSModule/includes/hooks/websitepanel_sync.php b/WebsitePanel.WHMCSModule/includes/hooks/websitepanel_sync.php
index 46a7a10e..0de3f28d 100644
--- a/WebsitePanel.WHMCSModule/includes/hooks/websitepanel_sync.php
+++ b/WebsitePanel.WHMCSModule/includes/hooks/websitepanel_sync.php
@@ -50,17 +50,19 @@ function websitepanel_sync_ClientEdit($params)
{
// Include the WebsitePanel ES Class
require_once(ROOTDIR . '/modules/servers/websitepanel/websitepanel.class.php');
+ require_once(ROOTDIR . '/modules/servers/websitepanel/websitepanel.functions.php');
// Retrieve the WebsitePanel Addons module settings
$modSettings = websitepanel_sync_GetSettings();
- if (empty($modSettings['username']) || empty($modSettings['password']) || empty($modSettings['serverhost']) || empty($modSettings['serverport']))
+ $srvSettings = websitepanel_GetServerSettings();
+ if (empty($modSettings['serverhost']) || empty($modSettings['serverport']) || empty($srvSettings['username']) || empty($srvSettings['password']))
{
// The module is disabled or has not yet been configured - stop
return;
}
// Create the WebsitePanel object instance
- $wsp = new WebsitePanel($modSettings['username'], $modSettings['password'], $modSettings['serverhost'], $modSettings['serverport'], (($modSettings['serversecured']) == 'on' ? TRUE : FALSE));
+ $wsp = new WebsitePanel($srvSettings['username'], $srvSettings['password'], $modSettings['serverhost'], $modSettings['serverport'], (($modSettings['serversecured']) == 'on' ? TRUE : FALSE));
// Get all WSP users with the old email
$items = (array)$wsp->get_users_paged_recursive(1, 'Email', $params['olddata']['email'], 0, 0, '');
diff --git a/WebsitePanel.WHMCSModule/modules/addons/websitepanel_addons/websitepanel_addons.php b/WebsitePanel.WHMCSModule/modules/addons/websitepanel_addons/websitepanel_addons.php
index 6bee05b3..13ce02bb 100644
--- a/WebsitePanel.WHMCSModule/modules/addons/websitepanel_addons/websitepanel_addons.php
+++ b/WebsitePanel.WHMCSModule/modules/addons/websitepanel_addons/websitepanel_addons.php
@@ -46,13 +46,11 @@ function websitepanel_addons_config()
{
$configarray = array('name' => 'WebsitePanel Addons Automation',
'description' => 'Automates WHMCS product addons with WebsitePanel',
- 'version' => '1.0',
+ 'version' => '1.2',
'author' => 'Christopher York',
'fields' => array('serverhost' => array('FriendlyName', 'Enterprise Server Host', 'Type' => 'text', 'Size' => 25, 'Description' => 'Enterprise Server hostname / IP address', 'Default' => '127.0.0.1'),
'serverport' => array('FriendlyName', 'Enterprise Server Port', 'Type' => 'text', 'Size' => 4, 'Description' => 'Enterprise Server port', 'Default' => 9002),
'serversecured' => array('FriendlyName', 'Use Secured Connection', 'Type' => 'yesno', 'Description' => 'Tick to use SSL secured connection'),
- 'username' => array('FriendlyName', 'Username', 'Type' => 'text', 'Size' => 25, 'Description' => 'Enterprise Server username', 'Default' => 'serveradmin'),
- 'password' => array('FriendlyName', 'Password', 'Type' => 'password', 'Size' => 25, 'Description' => 'Enterprise Server password')
)
);
return $configarray;
@@ -67,7 +65,7 @@ function websitepanel_addons_config()
function websitepanel_addons_activate()
{
// Create the WebsitePanel Addons table
- $query = "CREATE TABLE `tblwspaddons` (
+ $query = "CREATE TABLE `mod_wspaddons` (
`whmcs_id` int(11) NOT NULL,
`wsp_id` int(11) NOT NULL,
`is_ipaddress` bit(1) NOT NULL DEFAULT b'0',
@@ -94,9 +92,8 @@ function websitepanel_addons_activate()
*/
function websitepanel_addons_deactivate()
{
- // Create the WebsitePanel Addons table
- $query = 'DROP TABLE `tblwspaddons`';
- $result = full_query($query);
+ // Drop the WebsitePanel Addons table
+ $result = full_query('DROP TABLE `mod_wspaddons`');
// Check the results to verify that the table has been created properly
if (!$result)
@@ -109,6 +106,27 @@ function websitepanel_addons_deactivate()
}
}
+/**
+ * websitepanel_addons_upgrade
+ *
+ * @param $vars array
+ * @access public
+ * @return array
+ */
+function websitepanel_addons_upgrade($vars)
+{
+
+ $version = $vars['version'];
+
+ // Adjust the table name and remove the WebsitePanel credentials
+ if ($version < 1.2)
+ {
+ full_query('RENAME TABLE `tblwspaddons` TO `mod_wspaddons`');
+ full_query("DELETE FROM `tbladdonmodules` WHERE `module` = 'websitepanel_addons' AND `setting` = 'username'");
+ full_query("DELETE FROM `tbladdonmodules` WHERE `module` = 'websitepanel_addons' AND `setting` = 'password'");
+ }
+}
+
/**
* websitepanel_addons_output
*
@@ -120,24 +138,24 @@ function websitepanel_addons_output($params)
// Delete the requested WebsitePanel addon
if (isset($_GET['action']) && $_GET['action'] == 'delete')
{
- delete_query('tblwspaddons', array('whmcs_id' => $_GET['id']));
+ delete_query('mod_wspaddons', array('whmcs_id' => $_GET['id']));
}
// Add the requested WebsitePanel addon
if ($_POST && isset($_POST['action']) && $_POST['action'] == 'add')
{
// Sanity check to make sure the WHMCS addon ID exists
- $results = select_query('tbladdons', 'id', array('id' => $_POST['whmcs_id']));
+ $results = select_query('mod_wspaddons', 'id', array('id' => $_POST['whmcs_id']));
if (mysql_num_rows($results) > 0)
{
- $results = select_query('tblwspaddons', 'whmcs_id', array('whmcs_id' => $_POST['whmcs_id']));
+ $results = select_query('mod_wspaddons', 'whmcs_id', array('whmcs_id' => $_POST['whmcs_id']));
if (mysql_num_rows($results) > 0)
{
echo '
Duplicate WHMCS Addon ID. The WHMCS Addon ID Is Assigned To Another WebsitePanel Addon.
';
}
else
{
- insert_query('tblwspaddons', array('whmcs_id' => $_POST['whmcs_id'], 'wsp_id' => $_POST['wsp_id'], 'is_ipaddress' => $_POST['is_ipaddress']));
+ insert_query('mod_wspaddons', array('whmcs_id' => $_POST['whmcs_id'], 'wsp_id' => $_POST['wsp_id'], 'is_ipaddress' => $_POST['is_ipaddress']));
}
}
else
@@ -147,7 +165,7 @@ function websitepanel_addons_output($params)
}
// Get all the assigned addons and display them to the user
- $results = full_query('SELECT a.name AS `name`, a.id AS `whmcs_id`, w.wsp_id AS `wsp_id` FROM `tbladdons` AS a, `tblwspaddons` AS w WHERE w.whmcs_id = a.id');
+ $results = full_query('SELECT a.name AS `name`, a.id AS `whmcs_id`, w.wsp_id AS `wsp_id` FROM `tbladdons` AS a, `mod_wspaddons` AS w WHERE w.whmcs_id = a.id');
// Build the table / data grid
echo '';
diff --git a/WebsitePanel.WHMCSModule/modules/addons/websitepanel_sync/websitepanel_sync.php b/WebsitePanel.WHMCSModule/modules/addons/websitepanel_sync/websitepanel_sync.php
index 8822fa44..1db0d327 100644
--- a/WebsitePanel.WHMCSModule/modules/addons/websitepanel_sync/websitepanel_sync.php
+++ b/WebsitePanel.WHMCSModule/modules/addons/websitepanel_sync/websitepanel_sync.php
@@ -46,14 +46,32 @@ function websitepanel_sync_config()
{
$configarray = array('name' => 'WebsitePanel Sync Automation',
'description' => 'Syncs WHMCS client details / contact changes with WebsitePanel',
- 'version' => '1.0',
+ 'version' => '1.2',
'author' => 'Christopher York',
'fields' => array('serverhost' => array('FriendlyName', 'Enterprise Server Host', 'Type' => 'text', 'Size' => 25, 'Description' => 'Enterprise Server hostname / IP address', 'Default' => '127.0.0.1'),
'serverport' => array('FriendlyName', 'Enterprise Server Port', 'Type' => 'text', 'Size' => 4, 'Description' => 'Enterprise Server port', 'Default' => 9002),
'serversecured' => array('FriendlyName', 'Use Secured Connection', 'Type' => 'yesno', 'Description' => 'Tick to use SSL secured connection'),
- 'username' => array('FriendlyName', 'Username', 'Type' => 'text', 'Size' => 25, 'Description' => 'Enterprise Server username', 'Default' => 'serveradmin'),
- 'password' => array('FriendlyName', 'Password', 'Type' => 'password', 'Size' => 25, 'Description' => 'Enterprise Server password')
)
);
return $configarray;
+}
+
+/**
+ * websitepanel_addons_upgrade
+ *
+ * @param $vars array
+ * @access public
+ * @return array
+ */
+function websitepanel_sync_upgrade($vars)
+{
+
+ $version = $vars['version'];
+
+ // Remove the WebsitePanel credentials
+ if ($version < 1.2)
+ {
+ full_query("DELETE FROM `tbladdonmodules` WHERE `module` = 'websitepanel_sync' AND `setting` = 'username'");
+ full_query("DELETE FROM `tbladdonmodules` WHERE `module` = 'websitepanel_sync' AND `setting` = 'password'");
+ }
}
\ No newline at end of file
diff --git a/WebsitePanel.WHMCSModule/modules/servers/websitepanel/websitepanel.errorcodes.php b/WebsitePanel.WHMCSModule/modules/servers/websitepanel/websitepanel.errorcodes.php
index 8ce934d1..5bde4a57 100644
--- a/WebsitePanel.WHMCSModule/modules/servers/websitepanel/websitepanel.errorcodes.php
+++ b/WebsitePanel.WHMCSModule/modules/servers/websitepanel/websitepanel.errorcodes.php
@@ -39,15 +39,22 @@
/**
* Common error codes encountered while using the WebsitePanel Server Module
* These are not all the Enterprise Server error codes, only the ones I have encountered using the API
+ *
+ * @access public
+ * @return array
*/
-$esErrorCodes = array(-100 => 'User already exists',
- -101 => 'User not found',
- -102 => 'User has child user accounts',
- -300 => 'Hosting package could not be found',
- -301 => 'Hosting package has child hosting spaces',
- -501 => 'The sub-domain belongs to an existing hosting space that does not allow sub-domains to be created',
- -502 => 'The domain or sub-domain exists within another hosting space',
- -511 => 'Instant alias is enabled, but not configured',
- -601 => 'The website already exists on the target hosting space',
- -700 => 'The email domain already exists on the target hosting space',
- -1100 => 'User already exists');
\ No newline at end of file
+function websitepanel_GetEnterpriseServerErrors()
+{
+ $esErrorCodes = array(-100 => 'User already exists',
+ -101 => 'User not found',
+ -102 => 'User has child user accounts',
+ -300 => 'Hosting package could not be found',
+ -301 => 'Hosting package has child hosting spaces',
+ -501 => 'The sub-domain belongs to an existing hosting space that does not allow sub-domains to be created',
+ -502 => 'The domain or sub-domain exists within another hosting space',
+ -511 => 'Instant alias is enabled, but not configured',
+ -601 => 'The website already exists on the target hosting space',
+ -700 => 'The email domain already exists on the target hosting space',
+ -1100 => 'User already exists');
+ return $esErrorCodes;
+}
\ No newline at end of file
diff --git a/WebsitePanel.WHMCSModule/modules/servers/websitepanel/websitepanel.functions.php b/WebsitePanel.WHMCSModule/modules/servers/websitepanel/websitepanel.functions.php
index 6305669a..b41b2ddc 100644
--- a/WebsitePanel.WHMCSModule/modules/servers/websitepanel/websitepanel.functions.php
+++ b/WebsitePanel.WHMCSModule/modules/servers/websitepanel/websitepanel.functions.php
@@ -45,8 +45,14 @@
*/
function websitepanel_GetErrorMessage($code)
{
- global $esErrorCodes;
+ // Error codes
+ $esErrorCodes = array();
+ // Include the common / known error codes
+ require_once(ROOTDIR . '/modules/servers/websitepanel/websitepanel.errorcodes.php');
+ $esErrorCodes = websitepanel_GetEnterpriseServerErrors();
+
+ // Check if the error code exists, if not return the code
if (array_key_exists($code, $esErrorCodes))
{
return $esErrorCodes[$code];
@@ -167,4 +173,25 @@ function websitepanel_CalculateUsage($result, $usageType)
}
}
return $total;
+}
+
+/**
+ * websitepanel_GetServerSettings
+ *
+ * @access public
+ * @return array
+ */
+function websitepanel_GetServerSettings()
+{
+ $settings = array('username' => '', 'password' => '');
+
+ // Retrieve the settings from the modules configuration table
+ $results = select_query('tblservers', 'username,password', array('type' => 'websitepanel'));
+ if (mysql_num_rows($results) != 0)
+ {
+ $row = mysql_fetch_array($results, MYSQL_ASSOC);
+ $settings['username'] = $row['username'];
+ $settings['password'] = decrypt($row['password']);
+ }
+ return $settings;
}
\ No newline at end of file
diff --git a/WebsitePanel.WHMCSModule/readme.txt b/WebsitePanel.WHMCSModule/readme.txt
index dade497c..f45ca9c4 100644
--- a/WebsitePanel.WHMCSModule/readme.txt
+++ b/WebsitePanel.WHMCSModule/readme.txt
@@ -13,7 +13,7 @@ To enable addon automation...
What does not work?
- Quantities, only a single addon => addon can be allocated
- Terminating / Suspending Addons, I've ran out of time on what I can do currently
-- When an IP address is allocated WebsitePanel does not return back what IP was allocated, so WHMCS is not updated which what IP has been allocated to his / her package at this time.
+- When an IP address is allocated, WebsitePanel does not return back what IP was allocated, so WHMCS is not updated with which IP was assigned to the users hosting space
- A single user => single package is the only way the WebsitePanel server module works. I have no plans on making this work any other way.
DO NOT CONTACT WHMCS FOR SUPPORT WITH THIS MODULE - THIS IS NOT DEVELOPED BY WHMCS AND HAS NO AFFILIATION WITH WHMCS OR WHMCS.COM.
\ No newline at end of file
diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Common/WebPlatformInstaller.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Common/WebPlatformInstaller.cs
new file mode 100644
index 00000000..d7e28612
--- /dev/null
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Common/WebPlatformInstaller.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace WebsitePanel.EnterpriseServer.Base.Common
+{
+ public class WebPlatformInstaller
+ {
+ public const string MAIN_FEED_URL = "https://www.microsoft.com/web/webpi/4.2/webproductlist.xml";
+ public const string ZOO_FEED = "http://www.helicontech.com/zoo/feed/wsp4";
+ }
+}
diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/System/SystemSettings.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/System/SystemSettings.cs
index 904dec23..76778a16 100644
--- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/System/SystemSettings.cs
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/System/SystemSettings.cs
@@ -42,6 +42,10 @@ namespace WebsitePanel.EnterpriseServer
public const string BACKUP_SETTINGS = "BackupSettings";
public const string SETUP_SETTINGS = "SetupSettings";
public const string WPI_SETTINGS = "WpiSettings";
+
+ // key to access to wpi main & custom feed in wpi settings
+ public const string WPI_MAIN_FEED_KEY = "WpiMainFeedUrl";
+ public const string FEED_ULS_KEY = "FeedUrls";
public static readonly SystemSettings Empty = new SystemSettings { SettingsArray = new string[][] {} };
diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/WebsitePanel.EnterpriseServer.Base.csproj b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/WebsitePanel.EnterpriseServer.Base.csproj
index 9350215a..2168e6e3 100644
--- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/WebsitePanel.EnterpriseServer.Base.csproj
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/WebsitePanel.EnterpriseServer.Base.csproj
@@ -74,6 +74,7 @@
Code
+
diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/Code/WebAppGallery/WebAppGalleryController.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/Code/WebAppGallery/WebAppGalleryController.cs
index ff0f06d2..e4fb539b 100644
--- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/Code/WebAppGallery/WebAppGalleryController.cs
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/Code/WebAppGallery/WebAppGalleryController.cs
@@ -29,15 +29,14 @@
using System;
using System.Collections.Generic;
using System.Threading;
-using WebsitePanel.Providers.Web;
+using WebsitePanel.EnterpriseServer.Base.Common;
+using WebsitePanel.Providers.Web;
using WebsitePanel.Providers.ResultObjects;
using WebsitePanel.Providers.Database;
using WebsitePanel.Providers.WebAppGallery;
using System.Collections.Specialized;
-using System.Reflection;
using WebsitePanel.Providers.Common;
using System.Diagnostics;
-using System.IO;
namespace WebsitePanel.EnterpriseServer
{
@@ -72,28 +71,33 @@ namespace WebsitePanel.EnterpriseServer
private static string[] getFeedsFromSettingsByServiceId(int serviceId)
{
- StringDictionary serviceSettings = ServerController.GetServiceSettings(serviceId);
+ var wpiSettings = SystemController.GetSystemSettings(SystemSettings.WPI_SETTINGS);
- List
arFeeds = new List();
+ List feeds = new List();
- if (Utils.ParseBool(serviceSettings["FeedEnableMicrosoft"], true))
+ // Microsoft feed
+ string mainFeedUrl = wpiSettings[SystemSettings.WPI_MAIN_FEED_KEY];
+ if (string.IsNullOrEmpty(mainFeedUrl))
{
- arFeeds.Add(esServers.MAIN_WPI_FEED);
+ mainFeedUrl = WebPlatformInstaller.MAIN_FEED_URL;
}
+ feeds.Add(mainFeedUrl);
- if (Utils.ParseBool(serviceSettings["FeedEnableHelicon"], true))
- {
- arFeeds.Add(esServers.HELICON_WPI_FEED);
- }
+ // Zoo Feed
+ feeds.Add(WebPlatformInstaller.ZOO_FEED);
- string additionalFeeds = serviceSettings["FeedUrls"];
+
+ // additional feeds
+ string additionalFeeds = wpiSettings[SystemSettings.FEED_ULS_KEY];
if (!string.IsNullOrEmpty(additionalFeeds))
{
- arFeeds.AddRange(additionalFeeds.Split(';'));
+ feeds.AddRange(additionalFeeds.Split(';'));
}
- return arFeeds.ToArray();
+ return feeds.ToArray();
}
+
+
public static void InitFeedsByServiceId(int UserId, int serviceId)
{
string[] feeds = getFeedsFromSettingsByServiceId(serviceId);
diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esServers.asmx.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esServers.asmx.cs
index c9f4a3b2..982c6f11 100644
--- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esServers.asmx.cs
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esServers.asmx.cs
@@ -35,6 +35,7 @@ using System.Collections.Generic;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.ComponentModel;
+using WebsitePanel.EnterpriseServer.Base.Common;
using WebsitePanel.Providers.Common;
using Microsoft.Web.Services3;
@@ -54,8 +55,10 @@ namespace WebsitePanel.EnterpriseServer
[ToolboxItem(false)]
public class esServers : System.Web.Services.WebService
{
- public const string MAIN_WPI_FEED = "https://www.microsoft.com/web/webpi/4.0/WebProductList.xml";
+ /*
+ public const string MAIN_WPI_FEED = "https://www.microsoft.com/web/webpi/4.2/WebProductList.xml";
public const string HELICON_WPI_FEED = "http://www.helicontech.com/zoo/feed/wsp4";
+ */
#region Servers
[WebMethod]
@@ -696,25 +699,28 @@ namespace WebsitePanel.EnterpriseServer
var wpiSettings = SystemController.GetSystemSettings(SystemSettings.WPI_SETTINGS);
- List arFeeds = new List();
+ List feeds = new List();
- if (Utils.ParseBool(wpiSettings["FeedEnableMicrosoft"] ,true))
+ // Microsoft feed
+ string mainFeedUrl = wpiSettings[SystemSettings.WPI_MAIN_FEED_KEY];
+ if (string.IsNullOrEmpty(mainFeedUrl))
{
- arFeeds.Add( MAIN_WPI_FEED );
+ mainFeedUrl = WebPlatformInstaller.MAIN_FEED_URL;
}
+ feeds.Add(mainFeedUrl);
- if (Utils.ParseBool(wpiSettings["FeedEnableHelicon"] ,true))
- {
- arFeeds.Add( HELICON_WPI_FEED );
- }
-
- string additionalFeeds = wpiSettings["FeedUrls"];
+ // Zoo Feed
+ feeds.Add(WebPlatformInstaller.ZOO_FEED);
+
+
+ // additional feeds
+ string additionalFeeds = wpiSettings[SystemSettings.FEED_ULS_KEY];
if (!string.IsNullOrEmpty(additionalFeeds))
{
- arFeeds.AddRange(additionalFeeds.Split(';'));
+ feeds.AddRange(additionalFeeds.Split(';'));
}
- OperatingSystemController.InitWPIFeeds(serverId, string.Join(";", arFeeds));
+ OperatingSystemController.InitWPIFeeds(serverId, string.Join(";", feeds));
}
diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/IIs60.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/IIs60.cs
index 4aa4e55b..5319504f 100644
--- a/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/IIs60.cs
+++ b/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/IIs60.cs
@@ -279,7 +279,8 @@ namespace WebsitePanel.Providers.Web
get { return FileUtils.EvaluateSystemVariables(ProviderSettings["ProtectedFoldersFile"]); }
}
- protected string GalleryXmlFeedUrl
+ /*
+ protected string GalleryXmlFeedUrl
{
get
{
@@ -289,6 +290,7 @@ namespace WebsitePanel.Providers.Web
return ret;
}
}
+ */
#endregion
private WmiHelper wmi = null;
diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/WebApplicationGallery.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/WebApplicationGallery.cs
deleted file mode 100644
index 913e9a2a..00000000
--- a/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/WebApplicationGallery.cs
+++ /dev/null
@@ -1,943 +0,0 @@
-// Copyright (c) 2012, Outercurve Foundation.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without modification,
-// are permitted provided that the following conditions are met:
-//
-// - Redistributions of source code must retain the above copyright notice, this
-// list of conditions and the following disclaimer.
-//
-// - Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-//
-// - Neither the name of the Outercurve Foundation nor the names of its
-// contributors may be used to endorse or promote products derived from this
-// software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-using System.Xml;
-using System.Xml.Serialization;
-
-using Microsoft.Practices.EnterpriseLibrary.Caching;
-using System.Net;
-using System.IO;
-using WebsitePanel.Server.Utils;
-using WebsitePanel.Providers.WebAppGallery;
-using System.Text.RegularExpressions;
-using System.Web;
-using System.Reflection;
-using Microsoft.Web.Deployment;
-using System.Diagnostics;
-using System.Threading;
-using System.Security.Cryptography;
-using System.Collections;
-using Microsoft.Win32;
-using System.Linq;
-
-namespace WebsitePanel.Providers.Web
-{
- [Obsolete]
- public sealed class WebApplicationGallery
- {
- // MS Deploy library
- private const string MS_DEPLOY_ASSEMBLY_NAME = "Microsoft.Web.Deployment";
-
- private CacheManager cache;
- private static DeploymentSkipDirective SkipMsSQL = new DeploymentSkipDirective("skipSqlDirective", "objectName=dbFullSql");
- private static DeploymentSkipDirective SkipMySQL = new DeploymentSkipDirective("skipSqlDirective", "objectName=dbMySql");
-
- public const string AtomFeedNamespace = "http://www.w3.org/2005/Atom";
-
- public static string WEB_PI_USER_AGENT_HEADER = "Platform-Installer/{0}({1})";
- public const string WEB_PI_APP_PACK_ROOT_INSTALLER_ITEM_MISSING = "Root installer item for the {0} application could not be found. Please contact your Web Application Gallery feed provider to resolve the error.";
- public const string WEB_PI_APP_PACK_DISPLAY_URL_MISSING = "Web application '{0}' could not be downloaded as installer displayURL is empty or missing.";
-
- // web application gallery
- public const string WAG_XML_FEED_CACHE_KEY = "WAG_XML_FEED_CACHE_KEY";
- public const int WEB_APPLICATIONS_CACHE_STORE_MINUTES = 60;
- public const int XML_FEED_RECOVERY_ATTEMPTS = 10;
- // public const string WAG_DEFAULT_FEED_URL = "https://www.microsoft.com/web/webpi/3.0/WebApplicationList.xml";
- public const string WAG_DEFAULT_FEED_URL = "https://www.microsoft.com/web/webpi/4.0/webapplicationlist.xml";
-
- // well-known parameters matching
- public readonly Dictionary wellKnownParameters
- = new Dictionary(StringComparer.InvariantCultureIgnoreCase)
- {
- {"Database Server", DeploymentParameterWellKnownTag.DBServer},
- {"Database Administrator", DeploymentParameterWellKnownTag.DBAdminUserName},
- {"Database Administrator Password", DeploymentParameterWellKnownTag.DBAdminPassword},
- {"Database Name", DeploymentParameterWellKnownTag.DBName},
- {"Database User Name", DeploymentParameterWellKnownTag.DBUserName},
- {"Database Password", DeploymentParameterWellKnownTag.DBUserPassword}
- };
-
- // well-known dependencies matching
- public readonly Dictionary wellKnownDependencies
- = new Dictionary(StringComparer.InvariantCultureIgnoreCase)
- {
- {"ASPNETApp", GalleryApplicationWellKnownDependency.AspNet20},
- {"ASPNET35App", GalleryApplicationWellKnownDependency.AspNet20},
- {"MVCApp", GalleryApplicationWellKnownDependency.AspNet20},
- {"ASPNET4App", GalleryApplicationWellKnownDependency.AspNet40},
- {"PHPApp", GalleryApplicationWellKnownDependency.PHP},
- {"SQLApp", GalleryApplicationWellKnownDependency.SQL},
- {"SQLDriverPHPApp", GalleryApplicationWellKnownDependency.SQL},
- {"MySQLApp", GalleryApplicationWellKnownDependency.MySQL}
- };
-
- private string feedXmlURI;
-
- static WebApplicationGallery()
- {
- AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_MSDeploy_AssemblyResolve);
- }
-
- static Assembly CurrentDomain_MSDeploy_AssemblyResolve(object sender, ResolveEventArgs args)
- {
- // Ensure we resolve MSDeploy assembly
- if (args.Name.StartsWith(MS_DEPLOY_ASSEMBLY_NAME) == false)
- return null;
- //
- var regkey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\IIS Extensions\MSDeploy");
- //
- if (regkey == null)
- return null;
- // Always start with the most recent version of MSDeploy
- var versionKeys = regkey.GetSubKeyNames().OrderByDescending(x => x).ToArray();
- // Log all version keys found
- Array.ForEach(versionKeys, (x) => { Log.WriteInfo("MSDeploy version key found: {0}", x); });
- // Determine appropriate key name to query for
- var installPathKey = (IntPtr.Size == 8) ? "InstallPath" : "InstallPath_x86";
-
- // Check if running in 32bit mode under 64bit Windows (WOW64) - works with .NET 2.0+
- if (Environment.GetEnvironmentVariable("PROCESSOR_ARCHITEW6432") == "AMD64")
- {
- installPathKey = "InstallPath_x64";
- }
-
- var fileVersion = String.Empty;
- //
- var libPath = String.Empty;
- //
- for (int i = 0; i < versionKeys.Length; i++)
- {
- var versionKey = regkey.OpenSubKey(versionKeys[i]);
- //
- libPath = Path.Combine(versionKey.GetValue(installPathKey).ToString(), String.Concat(MS_DEPLOY_ASSEMBLY_NAME, ".dll"));
- //
- Log.WriteInfo("MSDeploy v{0}; Lib Path: {1}", versionKeys[i], libPath);
- //
- if (File.Exists(libPath) == true)
- {
- Log.WriteInfo("MSDeploy Lib Path: {0};", libPath);
- var fileVerInfo = FileVersionInfo.GetVersionInfo(libPath);
- //
- WEB_PI_USER_AGENT_HEADER = String.Format(WEB_PI_USER_AGENT_HEADER, fileVerInfo.FileVersion, Environment.OSVersion.VersionString);
- //
- break;
- }
- }
- //
- if (String.IsNullOrEmpty(libPath) == false)
- return Assembly.LoadFrom(libPath);
- //
- return null;
- }
-
- public WebApplicationGallery()
- : this(WAG_DEFAULT_FEED_URL)
- {
- }
-
- public WebApplicationGallery(string feedXmlURI)
- {
- cache = CacheFactory.GetCacheManager();
- //
- this.feedXmlURI = feedXmlURI;
- }
-
- public XmlDocument GetServiceXmlFeed()
- {
- XmlDocument xmldoc = (XmlDocument)cache[WAG_XML_FEED_CACHE_KEY];
- //
- if (xmldoc == null)
- {
- // First trying to load as usual...
- try
- {
- //
- xmldoc = new XmlDocument();
- xmldoc.Load(feedXmlURI);
-
- // Add XML to the cache
- cache.Add(WAG_XML_FEED_CACHE_KEY, xmldoc);
- }
- catch (Exception ex)
- {
- Log.WriteError(
- String.Format(@"Could not load xml feed in a usual way from '{0}',
-thus proceed to XML-FEED-RECOVERY section to try download it again in an advanced way.
-No action is required the message for information purposes only.", feedXmlURI), ex);
- }
- // Unable to load feed in the usual way, so lets try to "fix" content-encoding issue
- if (!xmldoc.HasChildNodes)
- {
- //
- int numOfRetries = 0;
- //
- try
- {
- WebClient wc = new WebClient();
- wc.Headers.Add(HttpRequestHeader.UserAgent, WEB_PI_USER_AGENT_HEADER);
- // Setting response encoding explicitly
- wc.Encoding = Encoding.UTF8;
- //
- string feedXmlString = wc.DownloadString(feedXmlURI);
- // Loading XML for several times with shift the from the beginning may helps
- // to eliminate encoding issue (somtimes several starting bytes are not recognized
- // by the parser and thus feed load is failed)
- do
- {
- try
- {
- xmldoc.LoadXml(feedXmlString.Substring(numOfRetries));
-
- // Add XML to the cache
- cache.Add(WAG_XML_FEED_CACHE_KEY, xmldoc);
- //
- Log.WriteInfo("XML feed has been successfully added into the cache. See its content below.");
- Log.WriteInfo(xmldoc.OuterXml);
- // Exit from the loop if XML is loaded successfully
- break;
- }
- catch(Exception ex)
- {
- // Log an exception
- Log.WriteError(
- String.Format("XML-FEED-RECOVERY is failed at {0} attempt. {1} attempts left.", numOfRetries, XML_FEED_RECOVERY_ATTEMPTS-numOfRetries), ex);
- //
- numOfRetries++;
- }
- }
- while (numOfRetries <= XML_FEED_RECOVERY_ATTEMPTS);
- }
- catch (Exception ex)
- {
- // Log an exception
- Log.WriteError(@"XML-FEED-RECOVERY is failed to recover the feed automatically.
-Please ensure that the feed is a correct XML file if you use a custom one,
-otherwise contact WebsitePanel Software for further assistance.", ex);
- }
- }
- ////
- //XmlNamespaceManager nsmgr = GetXmlNsManager(xmldoc.NameTable);
- ////
- //XmlNode rootNode = xmldoc.DocumentElement.SelectSingleNode("atom:dependencies", nsmgr);
- ////
- //XmlNodeList idRefNodes = rootNode.SelectNodes(".//atom:dependency[@idref]", nsmgr);
- ////
- //foreach (XmlNode idRefNode in idRefNodes)
- //{
- // //
- // XmlNode idRefRepo = xmldoc.DocumentElement.SelectSingleNode(
- // String.Format("//atom:dependency[@id='{0}']", idRefNode.Attributes["idref"].Value), nsmgr);
- // //
- // if (idRefRepo != null)
- // {
- // idRefNode.ParentNode.ReplaceChild(idRefRepo.Clone(), idRefNode);
- // }
- //}
-
- ////
- //idRefNodes = xmldoc.DocumentElement.SelectNodes("//atom:dependency[@idref]", nsmgr);
- ////
- //foreach (XmlNode idRefNode in idRefNodes)
- //{
- // //
- // XmlNode idRefRepo = xmldoc.DocumentElement.SelectSingleNode(
- // String.Format("//atom:dependency[@id='{0}']", idRefNode.Attributes["idref"].Value), nsmgr);
- // //
- // if (idRefRepo != null)
- // {
- // idRefNode.ParentNode.ReplaceChild(idRefRepo.Clone(), idRefNode);
- // }
- //}
- }
- //
- return xmldoc;
- }
-
- public bool IsMsDeployInstalled()
- {
- //
- try
- {
- Assembly.Load(MS_DEPLOY_ASSEMBLY_NAME);
- return true;
- }
- catch
- {
- // type could not be instantiated
- return false;
- }
- }
-
- public List GetCategories()
- {
- XmlDocument xmldoc = GetServiceXmlFeed();
- //
- if (xmldoc == null)
- return null;
-
- // get namespace manager
- XmlNamespaceManager nsmgr = GetXmlNsManager(xmldoc.NameTable);
-
- // get the list of all categories that are used by applications
- List appCategories = new List();
- foreach (XmlNode node in xmldoc.SelectNodes("//atom:entry[@type='application']/atom:keywords/atom:keywordId", nsmgr))
- appCategories.Add(node.InnerText);
-
- // get the list of all categories defined in the feed
- // and filter them
- List categories = new List();
- foreach (XmlNode node in xmldoc.SelectNodes("/atom:feed/atom:keywords/atom:keyword", nsmgr))
- {
- string id = node.Attributes["id"].Value;
- string name = node.InnerText;
- if(appCategories.Contains(id))
- categories.Add(new GalleryCategory { Id = id, Name = name });
- }
-
- return categories;
- }
-
- public List GetApplications(string categoryName)
- {
- XmlDocument xmldoc = GetServiceXmlFeed();
- //
- if (xmldoc == null)
- return null;
- //
- XmlNamespaceManager nsmgr = GetXmlNsManager(xmldoc.NameTable);
- //
- string xQuery = String.IsNullOrEmpty(categoryName) ? "//atom:entry[@type='application']"
- : String.Format("//atom:entry[@type='application' and atom:keywords[atom:keywordId='{0}']]", categoryName);
- //
- List appList = new List();
- //
- foreach (XmlNode node in xmldoc.SelectNodes(xQuery, nsmgr))
- {
- appList.Add(DeserializeGalleryApplication(node, nsmgr));
- }
-
- // sort apps alphabetically
- appList.Sort( (a,b) => { return String.Compare(a.Title, b.Title, true); });
-
- //
- return appList;
- }
-
- public GalleryApplication GetApplicationByProductId(string productId)
- {
- XmlDocument xmldoc = GetServiceXmlFeed();
- //
- if (xmldoc == null)
- return null;
- //
- XmlNamespaceManager nsmgr = GetXmlNsManager(xmldoc.NameTable);
- //
- string xQuery = String.Format("//atom:entry[@type='application' and atom:productId='{0}']", productId);
- //
- XmlNode node = xmldoc.SelectSingleNode(xQuery, nsmgr);
- //
- GalleryApplication app = DeserializeGalleryApplication(node, nsmgr);
- //
- return app;
- }
-
- public string GetApplicationPackagePath(string productId)
- {
- return GetApplicationPackagePath(GetApplicationByProductId(productId));
- }
-
- public string GetApplicationPackagePath(GalleryApplication app)
- {
- //
- string appPackagePath = null;
- //
- if (app != null)
- {
- InstallerFile installerFile = null;
- // Acquire root installer item
- #region Atom Feed Version 0.2
- if (app.InstallerItems.Count > 0)
- {
- InstallerItem installerItem_0 = app.InstallerItems[0];
- if (installerItem_0 == null)
- {
- Log.WriteWarning(WEB_PI_APP_PACK_ROOT_INSTALLER_ITEM_MISSING, app.Title);
- return appPackagePath;
- }
- // Ensure web app package can be reached
- installerFile = installerItem_0.InstallerFile;
- }
- #endregion
-
- #region Atom Feed Version 2.0.1.0
- else if (app.Installers.Count > 0)
- {
- Installer installerItem_0 = app.Installers[0];
- if (installerItem_0 == null)
- {
- Log.WriteWarning(WEB_PI_APP_PACK_ROOT_INSTALLER_ITEM_MISSING, app.Title);
- return appPackagePath;
- }
- // Ensure web app package can be reached
- installerFile = installerItem_0.InstallerFile;
- }
- #endregion
-
- if (installerFile == null || String.IsNullOrEmpty(installerFile.InstallerUrl))
- {
- Log.WriteWarning(WEB_PI_APP_PACK_DISPLAY_URL_MISSING, app.Title);
- return appPackagePath;
- }
- //
- Log.WriteInfo("Web App Download URL: {0}", installerFile.InstallerUrl);
- // Trying to match the original file name
- HttpWebRequest webReq = (HttpWebRequest)HttpWebRequest.Create(installerFile.InstallerUrl);
- {
- //
- Regex regex = new Regex("filename=\"(?.{0,})\"");
- string packageName = null;
- //
- webReq.UserAgent = WEB_PI_USER_AGENT_HEADER;
- //
- using (HttpWebResponse webResp = (HttpWebResponse)webReq.GetResponse())
- {
- string httpHeader = webResp.Headers["Content-Disposition"];
- //
- if (!String.IsNullOrEmpty(httpHeader))
- {
- string fileName = Array.Find(httpHeader.Split(';'),
- x => x.Trim().StartsWith("filename="));
- //
- Match match = regex.Match(fileName);
- // Match has been acquired
- if (match != null && match.Success)
- {
- packageName = match.Groups["packageName"].Value;
- }
- }
- }
- // Download URL points to the download package directly
- if (String.IsNullOrEmpty(packageName))
- {
- packageName = Path.GetFileName(installerFile.InstallerUrl);
- }
- //
- if (HttpContext.Current != null)
- {
- appPackagePath = HttpContext.Current.Server.MapPath(String.Format("~/App_Cache/{0}", packageName));
- }
- else
- {
- string assemblyPath = Path.GetDirectoryName(this.GetType().Assembly.Location);
- appPackagePath = Path.Combine(assemblyPath, String.Format(@"App_Cache\{0}", packageName));
- }
- }
- }
- //
- return appPackagePath;
- }
-
- public List GetApplicationParameters(string productId)
- {
- string packageFile = GetApplicationPackagePath(productId);
- //
- if (String.IsNullOrEmpty(packageFile))
- return null;
- //
- List appParams = new List();
- //
- DeploymentObject iisApplication = null;
- //
- try
- {
- iisApplication = DeploymentManager.CreateObject(DeploymentWellKnownProvider.Package, packageFile);
- //
- foreach (DeploymentSyncParameter parameter in iisApplication.SyncParameters)
- {
- DeploymentParameter p = new DeploymentParameter
- {
- Name = parameter.Name,
- FriendlyName = !String.IsNullOrEmpty(parameter.FriendlyName) ? parameter.FriendlyName : parameter.Name,
- Value = parameter.Value,
- DefaultValue = parameter.DefaultValue,
- Description = parameter.Description,
- ValidationKind = (DeploymentParameterValidationKind)parameter.Validation.Kind,
- ValidationString = parameter.Validation.ValidationString,
- WellKnownTags = (DeploymentParameterWellKnownTag)parameter.WellKnownTags
- };
-
- // add to the list
- appParams.Add(p);
-
- // fix tags for parameters with hard-coded names
- if(wellKnownParameters.ContainsKey(p.Name))
- p.WellKnownTags |= wellKnownParameters[p.Name];
- }
- }
- catch (Exception ex)
- {
- // Log an error
- Log.WriteError(
- String.Format("Could not read deployment parameters from '{0}' package.", packageFile), ex);
- //
- throw;
- }
- finally
- {
- if (iisApplication != null)
- iisApplication.Dispose();
- }
- //
- return appParams;
- }
-
- public string InstallApplication(string productId, List updatedParameters)
- {
- string packageFile = GetApplicationPackagePath(productId);
- string applicationPath = null;
-
- if (String.IsNullOrEmpty(packageFile))
- return null;
-
- Log.WriteInfo("WebApp Package Path: {0}", packageFile);
-
- if (!File.Exists(packageFile))
- throw new Exception(GalleryErrors.PackageFileNotFound);
-
- // Setup source deployment options
- DeploymentBaseOptions sourceOptions = new DeploymentBaseOptions();
-
- // Add tracing capabilities
- sourceOptions.Trace += new EventHandler(sourceOptions_Trace);
- sourceOptions.TraceLevel = TraceLevel.Verbose;
-
- // Setup deployment provider
- DeploymentProviderOptions providerOptions = new DeploymentProviderOptions(DeploymentWellKnownProvider.Package);
-
- // Set the package path location
- providerOptions.Path = packageFile;
-
- // Prepare the package deployment procedure
- using (DeploymentObject iisApplication = DeploymentManager.CreateObject(providerOptions, sourceOptions))
- {
- // Setup destination deployment options
- DeploymentBaseOptions destinationOptions = new DeploymentBaseOptions();
- // Add tracing capabilities
- destinationOptions.Trace += new EventHandler(sourceOptions_Trace);
- destinationOptions.TraceLevel = TraceLevel.Verbose;
-
- // MSDEPLOY TEAM COMMENTS: For each parameter that was specified in the UI, set its value
- DeploymentParameterWellKnownTag databaseEngine = DeploymentParameterWellKnownTag.None;
-
- int i = 0;
- while(i < iisApplication.SyncParameters.Count)
- {
- // try to find parameter in updated parameters
- string name = iisApplication.SyncParameters[i].Name;
- DeploymentParameter updatedParameter = updatedParameters.Find( p => { return String.Compare(p.Name, name) == 0; });
-
- if(updatedParameter != null)
- {
- // parameter found
- // update its value
- iisApplication.SyncParameters[i].Value = updatedParameter.Value;
- i++; // advance to the next parameter
-
- // check for selected database engine
- if ((updatedParameter.WellKnownTags & DeploymentParameterWellKnownTag.MySql) == DeploymentParameterWellKnownTag.MySql)
- databaseEngine = DeploymentParameterWellKnownTag.MySql;
- else if ((updatedParameter.WellKnownTags & DeploymentParameterWellKnownTag.Sql) == DeploymentParameterWellKnownTag.Sql)
- databaseEngine = DeploymentParameterWellKnownTag.Sql;
-
- // get application path
- if ((updatedParameter.WellKnownTags & DeploymentParameterWellKnownTag.IisApp) == DeploymentParameterWellKnownTag.IisApp)
- applicationPath = updatedParameter.Value;
- }
- else
- {
- // parameter not found
- // delete it
- iisApplication.SyncParameters.Remove(name);
- }
- }
-
-
- // Skip SQL Server database scripts if not SQL Server was selected
- if (databaseEngine != DeploymentParameterWellKnownTag.Sql)
- sourceOptions.SkipDirectives.Add(SkipMsSQL);
-
- // Skip MySQL database scripts if not MySQL was selected
- if (databaseEngine != DeploymentParameterWellKnownTag.MySql)
- sourceOptions.SkipDirectives.Add(SkipMySQL);
-
- // Setup deployment options
- DeploymentSyncOptions syncOptions = new DeploymentSyncOptions();
- // Add tracing capabilities
- //syncOptions..Action += new EventHandler(syncOptions_Action);
- // Issue a syncronization signal between the parties
- iisApplication.SyncTo(DeploymentWellKnownProvider.Auto, applicationPath, destinationOptions, syncOptions);
- //
- Log.WriteInfo("{0}: {1}", "Application path", applicationPath);
- //
- }
- //
- return applicationPath;
- }
-
- #region Helper methods
-
- private XmlNamespaceManager GetXmlNsManager(XmlNameTable nt)
- {
- XmlNamespaceManager nsmgr = new XmlNamespaceManager(nt);
- nsmgr.AddNamespace("atom", "http://www.w3.org/2005/Atom");
- //
- return nsmgr;
- }
-
- private GalleryApplication DeserializeGalleryApplication(XmlNode node, XmlNamespaceManager nsmgr)
- {
- XmlSerializer xs = new XmlSerializer(typeof(GalleryApplication), AtomFeedNamespace);
- GalleryApplication app = (GalleryApplication)xs.Deserialize(new XmlNodeReader(node));
- //
- app.LastUpdated = XmlToDateTime(GetAtomNodeText(node, nsmgr, "updated"), "yyyy-M-dTHH:mm:ssZ");
- app.Published = XmlToDateTime(GetAtomNodeText(node, nsmgr, "published"), "yyyy-M-dTHH:mm:ssZ");
- app.Link = GetAtomNodeAttribute(node, nsmgr, "link", "href");
- //
- app.IconUrl = GetAtomNodeText(node, nsmgr, "images/atom:icon");
-
- // parse well-known dependencies
- UpdateApplicationWellKnownDependencies(app, app.Dependency);
-
- //
- return app;
- }
-
- private void UpdateApplicationWellKnownDependencies(GalleryApplication app, Dependency dependency)
- {
- if (dependency == null)
- return;
-
- if (dependency.IdRef != null && wellKnownDependencies.ContainsKey(dependency.IdRef))
- app.WellKnownDependencies |= wellKnownDependencies[dependency.IdRef];
-
- // process "And"
- foreach (Dependency d in dependency.And)
- UpdateApplicationWellKnownDependencies(app, d);
-
- // process "Or"
- foreach (Dependency d in dependency.Or)
- UpdateApplicationWellKnownDependencies(app, d);
-
- // process "LogicalAnd"
- foreach (Dependency d in dependency.LogicalAnd)
- UpdateApplicationWellKnownDependencies(app, d);
-
- // process "LogicalOr"
- foreach (Dependency d in dependency.LogicalOr)
- UpdateApplicationWellKnownDependencies(app, d);
- }
-
- private string GetAtomNodeText(XmlNode app, XmlNamespaceManager nsmgr, string nodeName)
- {
- XmlNode node = app.SelectSingleNode("atom:" + nodeName, nsmgr);
- if (node == null)
- return null;
- return node.InnerText;
- }
-
- private string GetAtomNodeAttribute(XmlNode app, XmlNamespaceManager nsmgr, string nodeName, string attributeName)
- {
- XmlNode node = app.SelectSingleNode("atom:" + nodeName, nsmgr);
- if (node == null)
- return null;
- string ret = null;
- XmlAttribute attribute = node.Attributes[attributeName];
- if (attribute != null)
- ret = attribute.Value;
- return ret;
- }
-
- private DateTime XmlToDateTime(string val, string format)
- {
- DateTime ret = DateTime.MinValue;
-
- try
- {
- if (!string.IsNullOrEmpty(val))
- ret = XmlConvert.ToDateTime(val, format);
- }
- catch (Exception) { }
- return ret;
- }
-
- private static string GetAtomNodeText(XmlNode node)
- {
- if (node == null)
- return null;
- return node.InnerText;
- }
-
- private void sourceOptions_Trace(object sender, DeploymentTraceEventArgs e)
- {
- Log.WriteInfo(e.Message);
- Log.WriteInfo("Event Level: " + e.EventLevel);
- Log.WriteInfo("Event Data: ");
- //
- foreach (string keyName in e.EventData.Keys)
- {
- Log.WriteInfo(keyName + " => " + e.EventData[keyName]);
- }
- }
-
- /*private void syncOptions_Action(object sender, DeploymentActionEventArgs e)
- {
- Log.WriteInfo(e.Message);
- Log.WriteInfo("Operation Type: " + e.OperationType);
- Log.WriteInfo("Event Data: ");
- //
- foreach (string keyName in e.EventData.Keys)
- {
- Log.WriteInfo(keyName + " => " + e.EventData[keyName]);
- }
- }*/
-
- #endregion
- }
-
- public class DownloadQueueItem
- {
- public String ItemKey;
- public WebClient ConnectionPoint;
- public DownloadProgressChangedEventArgs Progress;
- public string DownloadItemURI;
- public string LocalFilePathToStore;
-
- public void StartItemDownloadAsync(Object state)
- {
- ConnectionPoint.DownloadFileAsync(new Uri(DownloadItemURI), LocalFilePathToStore);
- }
- }
-
- public sealed class AppPackagesDownloader
- {
- private static List downloadQueue;
-
- static AppPackagesDownloader()
- {
- downloadQueue = new List();
- }
-
- //
- public static bool CheckApplicationPackageHashSum_MD5(string localFilePath, string md5)
- {
- if (!File.Exists(localFilePath))
- return false;
- //
- bool md5OK = false;
- //
- try
- {
- //
- MD5 md5File = new MD5CryptoServiceProvider();
- //
- string fileMd5Sum = BitConverter.ToString(
- md5File.ComputeHash(File.ReadAllBytes(localFilePath))).Replace("-", String.Empty);
- //
- md5OK = String.Equals(md5, fileMd5Sum, StringComparison.InvariantCultureIgnoreCase);
- }
- catch (Exception ex)
- {
- Log.WriteError(String.Format("Failed to compute MD5 sum for {0} package.", localFilePath), ex);
- }
- //
- return md5OK;
- }
-
- //
- public static bool CheckApplicationPackageHashSum_SHA1(string localFilePath, string sha1)
- {
- if (!File.Exists(localFilePath))
- return false;
- //
- bool sha1OK = false;
- //
- try
- {
- //
- SHA1 sha1File = new SHA1CryptoServiceProvider();
- //
- string fileSha1Sum = BitConverter.ToString(
- sha1File.ComputeHash(File.ReadAllBytes(localFilePath))).Replace("-", String.Empty);
- //
- sha1OK = String.Equals(sha1, fileSha1Sum, StringComparison.InvariantCultureIgnoreCase);
- //
- if (!sha1OK)
- Log.WriteWarning("SHA1-XML FEED: {0}; SHA1-FILE ON DISK: {1};", sha1, fileSha1Sum);
- }
- catch (Exception ex)
- {
- Log.WriteError(String.Format("Failed to compute SHA1 sum for {0} package.", localFilePath), ex);
- }
- //
- return sha1OK;
- }
-
- //
- public static bool IsApplicationInDownloadQueue(string appName)
- {
- bool exists = false;
- //
- if (!String.IsNullOrEmpty(appName))
- {
- ICollection ic = downloadQueue as ICollection;
- //
- lock (ic.SyncRoot)
- {
- exists = Array.Exists(downloadQueue.ToArray(),
- x => x.ItemKey == appName.ToLower());
- }
- }
- //
- return exists;
- }
-
- //
- public static void StartApplicationDownload(string appName, string packageUrl, string localPathToStore)
- {
- //
- bool appInQueue = IsApplicationInDownloadQueue(appName);
- //
- if (!appInQueue)
- {
- ICollection ic = downloadQueue as ICollection;
- //
- lock (ic.SyncRoot)
- {
- //
- DownloadQueueItem qi = new DownloadQueueItem
- {
- ItemKey = appName.ToLower(),
- ConnectionPoint = new WebClient(),
- Progress = null
- };
- //
- qi.DownloadItemURI = packageUrl;
- qi.LocalFilePathToStore = localPathToStore;
- qi.ConnectionPoint.Headers.Add(HttpRequestHeader.UserAgent, WebApplicationGallery.WEB_PI_USER_AGENT_HEADER);
- qi.ConnectionPoint.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(wc_DownloadFileCompleted);
- qi.ConnectionPoint.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);
- //
- downloadQueue.Add(qi);
- // Start async download (10 attempts)
- int numOfAttempt = 0;
- do
- {
- try
- {
- bool success = ThreadPool.QueueUserWorkItem(
- new WaitCallback(qi.StartItemDownloadAsync));
- // Exit the loop if the item successfuly queued
- if (success)
- break;
- }
- catch (Exception ex)
- {
- numOfAttempt++;
- // Log an exception
- Log.WriteError(String.Format("Could not start distibutive download from the following URI: {0}", qi.DownloadItemURI), ex);
- }
- }
- while (numOfAttempt <= 10);
- }
- }
- }
-
- public static int GetApplicationDownloadProgress(string appName)
- {
- int appProgress = 0;
- //
- bool appInQueue = IsApplicationInDownloadQueue(appName);
- //
- if (appInQueue)
- {
- ICollection ic = downloadQueue as ICollection;
- //
- lock (ic.SyncRoot)
- {
- DownloadQueueItem qi = Array.Find(downloadQueue.ToArray(),
- x => x.ItemKey == appName.ToLower());
- //
- if (qi.Progress != null)
- appProgress = qi.Progress.ProgressPercentage;
- }
- }
- //
- return appProgress;
- }
-
- static void wc_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
- {
- ICollection ic = downloadQueue as ICollection;
- //
- lock (ic.SyncRoot)
- {
- DownloadQueueItem qi = Array.Find(downloadQueue.ToArray(),
- x => x.ConnectionPoint == sender);
- //
- if (e.Error != null)
- {
- //
- if (qi != null)
- Log.WriteError(String.Format("Could not download app {0}", qi.ItemKey), e.Error);
- else
- Log.WriteError(e.Error);
- }
- //
- downloadQueue.Remove(qi);
- }
- }
-
- static void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
- {
- ICollection ic = downloadQueue as ICollection;
- //
- lock (ic.SyncRoot)
- {
- DownloadQueueItem qi = Array.Find(downloadQueue.ToArray(),
- x => x.ConnectionPoint == sender);
-
- if (qi != null)
- qi.Progress = e;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/WebsitePanel.Providers.Web.IIs60.csproj b/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/WebsitePanel.Providers.Web.IIs60.csproj
index 3e06a8b4..d14ee66c 100644
--- a/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/WebsitePanel.Providers.Web.IIs60.csproj
+++ b/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/WebsitePanel.Providers.Web.IIs60.csproj
@@ -93,7 +93,6 @@
-
diff --git a/WebsitePanel/Sources/WebsitePanel.Server/Code/WPIHelper.cs b/WebsitePanel/Sources/WebsitePanel.Server/Code/WPIHelper.cs
index 09ec94c2..5ad0f643 100644
--- a/WebsitePanel/Sources/WebsitePanel.Server/Code/WPIHelper.cs
+++ b/WebsitePanel/Sources/WebsitePanel.Server/Code/WPIHelper.cs
@@ -55,10 +55,8 @@ namespace WebsitePanel.Server.Code
#region private fields
- private readonly List _feeds;
+ private List _feeds;
private string _webPIinstallersFolder;
- //private const string MainWpiFeed = "https://www.microsoft.com/web/webpi/3.0/webproductlist.xml";
- private const string MainWpiFeed = "https://www.microsoft.com/web/webpi/4.0/WebProductList.xml";
private const string IisChoiceProduct = "StaticContent";
private const string WebMatrixChoiceProduct = "WebMatrix";
private ProductManager _productManager;
@@ -79,6 +77,14 @@ namespace WebsitePanel.Server.Code
public WpiHelper(IEnumerable feeds)
{
+ // check feeds is not empty
+ if (null == feeds || !feeds.Any())
+ {
+ throw new Exception("WpiHelper error: empty feed list in constructor");
+ }
+
+
+ // by default feeds must contains main MS WPI feed url and Zoo feed url
_feeds = new List();
_feeds.AddRange(feeds);
@@ -135,7 +141,6 @@ namespace WebsitePanel.Server.Code
}
#endregion
-
#region Keywords
public ReadOnlyCollection GetKeywords()
{
@@ -158,8 +163,6 @@ namespace WebsitePanel.Server.Code
}
#endregion
-
-
#region Products
public List GetProductsToInstall(string FeedLocation, string keywordId)
{
@@ -546,6 +549,7 @@ namespace WebsitePanel.Server.Code
}
#endregion
+
#endregion Public interface
@@ -553,12 +557,6 @@ namespace WebsitePanel.Server.Code
private void Initialize()
{
- // insert Main WebPI xml file
- if (!_feeds.Contains(MainWpiFeed, StringComparer.OrdinalIgnoreCase))
- {
- _feeds.Insert(0, MainWpiFeed);
- }
-
// create cache folder if not exists
//_webPIinstallersFolder = Environment.ExpandEnvironmentVariables(@"%LocalAppData%\Microsoft\Web Platform Installer\installers");
_webPIinstallersFolder = Path.Combine(
@@ -570,28 +568,89 @@ namespace WebsitePanel.Server.Code
Directory.CreateDirectory(_webPIinstallersFolder);
}
- // load feeds
- _productManager = new ProductManager();
-
-
- foreach (string feed in _feeds)
- {
- WriteLog(string.Format("Loading feed {0}", feed));
- if (feed.StartsWith("https://www.microsoft.com", StringComparison.OrdinalIgnoreCase))
- {
- _productManager.Load(new Uri(feed), true, true, true, _webPIinstallersFolder);
- }
- else
- {
- _productManager.LoadExternalFile(new Uri(feed));
- }
- }
+ LoadFeeds();
WriteLog(string.Format("{0} products loaded", _productManager.Products.Count));
//LogDebugInfo();
}
+ private void LoadFeeds()
+ {
+ if (null == _feeds || !_feeds.Any())
+ {
+ throw new Exception("WpiHelper: no feeds provided");
+ }
+
+ _productManager = new ProductManager();
+
+ if (TryLoadFeeds())
+ {
+ // ok, all feeds loaded
+ }
+ else
+ {
+ // feed loading failed
+
+ if (_feeds.Count > 1)
+ {
+ // exclude feeds except first (default microsoft feed)
+ _feeds = new List {_feeds[0]};
+
+ // re-create product manager
+ _productManager = new ProductManager();
+ if (TryLoadFeeds())
+ {
+ // loaded first (default) feed only
+ }
+ else
+ {
+ throw new Exception(string.Format("WpiHelper: download all feeds failed"));
+ }
+ }
+ else
+ {
+ throw new Exception(string.Format("WpiHelper: download all feeds failed"));
+ }
+ }
+ }
+
+ private bool TryLoadFeeds()
+ {
+ string loadingFeed = null;
+
+ try
+ {
+ foreach (string feed in _feeds)
+ {
+ loadingFeed = feed;
+ WriteLog(string.Format("Loading feed {0}", feed));
+ if (feed.IndexOf("microsoft.com", StringComparison.OrdinalIgnoreCase) > 0)
+ {
+ // it is internal Microsoft feed
+ _productManager.Load(new Uri(feed), true, true, true, _webPIinstallersFolder);
+ }
+ else
+ {
+ _productManager.LoadExternalFile(new Uri(feed));
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ if (!string.IsNullOrEmpty(loadingFeed))
+ {
+ // error occured on loading this feed
+ // log this
+ WriteLog(string.Format("Feed {0} loading error: {1}", loadingFeed, ex));
+
+ return false;
+ }
+ }
+
+ return true;
+ }
+
private Language GetLanguage(string languageId)
{
if (!string.IsNullOrEmpty(languageId))
diff --git a/WebsitePanel/Sources/WebsitePanel.Server/WindowsServer.asmx.cs b/WebsitePanel/Sources/WebsitePanel.Server/WindowsServer.asmx.cs
index 8940e917..c6398bf5 100644
--- a/WebsitePanel/Sources/WebsitePanel.Server/WindowsServer.asmx.cs
+++ b/WebsitePanel/Sources/WebsitePanel.Server/WindowsServer.asmx.cs
@@ -477,11 +477,7 @@ namespace WebsitePanel.Server
}
- static string[] FEEDS = new string[]
- {
- // "https://www.microsoft.com/web/webpi/3.0/WebProductList.xml",
- // "http://www.helicontech.com/zoo/feed/"
- };
+ static private string[] _feeds = new string[]{};
[WebMethod]
public void InitWPIFeeds(string feedUrls)
@@ -491,18 +487,18 @@ namespace WebsitePanel.Server
throw new Exception("Empty feed list");
}
- string[] newFEEDS = feedUrls.Split(';');
+ string[] newFeeds = feedUrls.Split(';');
- if (newFEEDS.Length == 0)
+ if (newFeeds.Length == 0)
{
throw new Exception("Empty feed list");
}
- if (!ArraysEqual(newFEEDS, FEEDS))
+ if (!ArraysEqual(newFeeds, _feeds))
{
Log.WriteInfo("InitWPIFeeds - new value: " + feedUrls);
//Feeds settings have been channged
- FEEDS = newFEEDS;
+ _feeds = newFeeds;
wpi = null;
}
@@ -604,7 +600,7 @@ namespace WebsitePanel.Server
WPIServiceContract client = new WPIServiceContract();
- client.Initialize(FEEDS);
+ client.Initialize(_feeds);
client.BeginInstallation(products);
@@ -795,14 +791,14 @@ namespace WebsitePanel.Server
static WpiHelper wpi = null;
WpiHelper GetWpiFeed()
{
- if (FEEDS.Length == 0)
+ if (_feeds.Length == 0)
{
throw new Exception("Empty feed list");
}
if (null == wpi)
{
- wpi = new WpiHelper(FEEDS);
+ wpi = new WpiHelper(_feeds);
}
return wpi;
}
diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/App_LocalResources/SystemSettings.ascx.resx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/App_LocalResources/SystemSettings.ascx.resx
index 1b0c52e9..feb70193 100644
--- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/App_LocalResources/SystemSettings.ascx.resx
+++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/App_LocalResources/SystemSettings.ascx.resx
@@ -147,4 +147,10 @@
Enable SSL:
+
+ Main feed URL:
+
+
+ Custom feeds:
+
\ No newline at end of file
diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ServersEditWebPlatformInstaller.ascx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ServersEditWebPlatformInstaller.ascx
index 301eb036..9a656fa7 100644
--- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ServersEditWebPlatformInstaller.ascx
+++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ServersEditWebPlatformInstaller.ascx
@@ -32,6 +32,7 @@ ul.WPIKeywordList {
ul.WPIKeywordList>li {
padding: .4em .4em;
margin-right: .4em;
+ line-height: 2em;
display: inline;
list-style-type: none;
}
diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SystemSettings.ascx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SystemSettings.ascx
index f8d61d60..55b85a1a 100644
--- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SystemSettings.ascx
+++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SystemSettings.ascx
@@ -35,34 +35,28 @@
-
-
-
-<%--
+ TargetControlID="WpiPanel" meta:resourcekey="lclWpiSettings" Text="Web Platform Installer Settings"/>
+
+
+
- Enable Microsoft feed |
-
-
- |
+ |
+ |
-
- Enable HeliconTech feed |
-
-
+ | |
+
+
|
-
---%>
-
+