Skip to content

Commit 4fd2472

Browse files
authored
Merge pull request Azure#4396 from cormacpayne/telemetry-fix
Client-side telemetry is opt-in by default
2 parents f3ad702 + fa08219 commit 4fd2472

File tree

20 files changed

+187
-173
lines changed

20 files changed

+187
-173
lines changed

src/Common/Commands.Common/AzureDataCmdlet.cs

Lines changed: 7 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -111,48 +111,19 @@ protected override void SaveDataCollectionProfile()
111111
WriteWarning(string.Format(Resources.DataCollectionSaveFileInformation, fileFullPath));
112112
}
113113

114-
protected override void PromptForDataCollectionProfileIfNotExists()
114+
protected override void SetDataCollectionProfileIfNotExists()
115115
{
116-
// Initialize it from the environment variable or profile file.
117116
InitializeDataCollectionProfile();
118117

119-
if (!_dataCollectionProfile.EnableAzureDataCollection.HasValue && CheckIfInteractive())
118+
if (_dataCollectionProfile.EnableAzureDataCollection.HasValue)
120119
{
121-
WriteWarning(Resources.DataCollectionPrompt);
122-
123-
const double timeToWaitInSeconds = 60;
124-
var status = string.Format(Resources.DataCollectionConfirmTime, timeToWaitInSeconds);
125-
ProgressRecord record = new ProgressRecord(0, Resources.DataCollectionActivity, status);
126-
127-
var startTime = DateTime.Now;
128-
var endTime = DateTime.Now;
129-
double elapsedSeconds = 0;
130-
131-
while (!this.Host.UI.RawUI.KeyAvailable && elapsedSeconds < timeToWaitInSeconds)
132-
{
133-
TestMockSupport.Delay(10 * 1000);
134-
endTime = DateTime.Now;
135-
136-
elapsedSeconds = (endTime - startTime).TotalSeconds;
137-
record.PercentComplete = ((int)elapsedSeconds * 100 / (int)timeToWaitInSeconds);
138-
WriteProgress(record);
139-
}
140-
141-
bool enabled = false;
142-
if (this.Host.UI.RawUI.KeyAvailable)
143-
{
144-
KeyInfo keyInfo =
145-
this.Host.UI.RawUI.ReadKey(ReadKeyOptions.NoEcho | ReadKeyOptions.AllowCtrlC |
146-
ReadKeyOptions.IncludeKeyDown);
147-
enabled = (keyInfo.Character == 'Y' || keyInfo.Character == 'y');
148-
}
149-
150-
_dataCollectionProfile.EnableAzureDataCollection = enabled;
120+
return;
121+
}
151122

152-
WriteWarning(enabled ? Resources.DataCollectionConfirmYes : Resources.DataCollectionConfirmNo);
123+
WriteWarning(Resources.RDFEDataCollectionMessage);
153124

154-
SaveDataCollectionProfile();
155-
}
125+
_dataCollectionProfile.EnableAzureDataCollection = true;
126+
SaveDataCollectionProfile();
156127
}
157128

158129
protected override void InitializeQosEvent()

src/Common/Commands.Common/AzurePSCmdlet.cs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -138,23 +138,32 @@ protected static void InitializeDataCollectionProfile()
138138
if (string.Equals(value, bool.FalseString, StringComparison.OrdinalIgnoreCase))
139139
{
140140
// Disable data collection only if it is explicitly set to 'false'.
141-
_dataCollectionProfile = new AzurePSDataCollectionProfile(true);
141+
_dataCollectionProfile = new AzurePSDataCollectionProfile(false);
142142
}
143143
else if (string.Equals(value, bool.TrueString, StringComparison.OrdinalIgnoreCase))
144144
{
145145
// Enable data collection only if it is explicitly set to 'true'.
146-
_dataCollectionProfile = new AzurePSDataCollectionProfile(false);
146+
_dataCollectionProfile = new AzurePSDataCollectionProfile(true);
147147
}
148148
}
149149

150150
// If the environment value is null or empty, or not correctly set, try to read the setting from default file location.
151151
if (_dataCollectionProfile == null)
152152
{
153+
// If it exists, remove the old AzureDataCollectionProfile.json file
154+
string oldFileFullPath = Path.Combine(AzurePowerShell.ProfileDirectory,
155+
AzurePSDataCollectionProfile.OldDefaultFileName);
156+
if (AzureSession.Instance.DataStore.FileExists(oldFileFullPath))
157+
{
158+
AzureSession.Instance.DataStore.DeleteFile(oldFileFullPath);
159+
}
160+
161+
// Try and read from the new AzurePSDataCollectionProfile.json file
153162
string fileFullPath = Path.Combine(AzurePowerShell.ProfileDirectory,
154163
AzurePSDataCollectionProfile.DefaultFileName);
155-
if (File.Exists(fileFullPath))
164+
if (AzureSession.Instance.DataStore.FileExists(fileFullPath))
156165
{
157-
string contents = File.ReadAllText(fileFullPath);
166+
string contents = AzureSession.Instance.DataStore.ReadFileAsText(fileFullPath);
158167
_dataCollectionProfile =
159168
JsonConvert.DeserializeObject<AzurePSDataCollectionProfile>(contents);
160169
}
@@ -234,7 +243,7 @@ protected bool CheckIfInteractive()
234243
/// <summary>
235244
/// Prompt for the current data collection profile
236245
/// </summary>
237-
protected abstract void PromptForDataCollectionProfileIfNotExists();
246+
protected abstract void SetDataCollectionProfileIfNotExists();
238247

239248
protected virtual void LogCmdletStartInvocationInfo()
240249
{
@@ -294,7 +303,7 @@ protected virtual void TearDownHttpClientPipeline()
294303
/// </summary>
295304
protected override void BeginProcessing()
296305
{
297-
PromptForDataCollectionProfileIfNotExists();
306+
SetDataCollectionProfileIfNotExists();
298307
InitializeQosEvent();
299308
LogCmdletStartInvocationInfo();
300309
SetupDebuggingTraces();

src/Common/Commands.Common/AzurePSDataCollectionProfile.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ namespace Microsoft.WindowsAzure.Commands.Common
1919
public class AzurePSDataCollectionProfile
2020
{
2121
public const string EnvironmentVariableName = "Azure_PS_Data_Collection";
22-
public static string DefaultFileName = "AzureDataCollectionProfile.json";
22+
public static string OldDefaultFileName = "AzureDataCollectionProfile.json";
23+
public static string DefaultFileName = "AzurePSDataCollectionProfile.json";
2324

2425
public AzurePSDataCollectionProfile()
2526
{

src/Common/Commands.Common/Extensions/CmdletExtensions.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// limitations under the License.
1313
// ----------------------------------------------------------------------------------
1414

15+
using Microsoft.WindowsAzure.Commands.Common;
1516
using System;
1617
using System.Collections.Generic;
1718
using System.Collections.ObjectModel;
@@ -216,6 +217,18 @@ public static void InvokeEndProcessing(this PSCmdlet cmdlt)
216217
dynMethod.Invoke(cmdlt, null);
217218
}
218219

220+
public static void EnableDataCollection(this AzurePSCmdlet cmdlt)
221+
{
222+
FieldInfo dynField = (typeof(AzurePSCmdlet)).GetField("_dataCollectionProfile", BindingFlags.NonPublic | BindingFlags.Static);
223+
dynField.SetValue(cmdlt, new AzurePSDataCollectionProfile(true));
224+
}
225+
226+
public static void DisableDataCollection(this AzurePSCmdlet cmdlt)
227+
{
228+
FieldInfo dynField = (typeof(AzurePSCmdlet)).GetField("_dataCollectionProfile", BindingFlags.NonPublic | BindingFlags.Static);
229+
dynField.SetValue(cmdlt, new AzurePSDataCollectionProfile(false));
230+
}
231+
219232
#endregion
220233
}
221234
}

src/Common/Commands.Common/MetricHelper.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
using System;
2222
using System.Collections.Generic;
2323
using System.Diagnostics;
24+
using System.Linq;
25+
using System.Net.NetworkInformation;
2426
using System.Security.Cryptography;
2527
using System.Text;
2628

@@ -52,6 +54,24 @@ public class MetricHelper
5254
/// </summary>
5355
private readonly object _lock = new object();
5456

57+
private static string _hashMacAddress = string.Empty;
58+
59+
private static string HashMacAddress
60+
{
61+
get
62+
{
63+
if (_hashMacAddress == string.Empty)
64+
{
65+
var macAddress = NetworkInterface.GetAllNetworkInterfaces()
66+
.FirstOrDefault(nic => nic.OperationalStatus == OperationalStatus.Up)?
67+
.GetPhysicalAddress()?.ToString();
68+
_hashMacAddress = macAddress == null ? null : GenerateSha256HashString(macAddress).Replace("-", string.Empty).ToLowerInvariant();
69+
}
70+
71+
return _hashMacAddress;
72+
}
73+
}
74+
5575
public MetricHelper()
5676
{
5777
if (TestMockSupport.RunningMocked)
@@ -177,6 +197,7 @@ private void PopulatePropertiesFromQos(AzurePSQoSEvent qos, IDictionary<string,
177197
eventProperties.Add("UserId", qos.Uid);
178198
eventProperties.Add("x-ms-client-request-id", qos.ClientRequestId);
179199
eventProperties.Add("UserAgent", AzurePowerShell.UserAgentValue.ToString());
200+
eventProperties.Add("HashMacAddress", HashMacAddress);
180201
if (qos.InputFromPipeline != null)
181202
{
182203
eventProperties.Add("InputFromPipeline", qos.InputFromPipeline.Value.ToString());

src/Common/Commands.Common/Properties/Resources.Designer.cs

Lines changed: 29 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Common/Commands.Common/Properties/Resources.resx

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1468,18 +1468,13 @@ The file needs to be a PowerShell script (.ps1 or .psm1).</value>
14681468
<data name="CannotChangeBuiltinEnvironment" xml:space="preserve">
14691469
<value>Cannot change built-in environment {0}.</value>
14701470
</data>
1471-
<data name="DataCollectionPrompt" xml:space="preserve">
1472-
<value>Microsoft Azure PowerShell collects data about how users use PowerShell cmdlets and some problems they encounter. Microsoft uses this information to improve our PowerShell cmdlets. Participation is voluntary and when you choose to participate your device automatically sends information to Microsoft about how you use Azure PowerShell.
1473-
1474-
If you choose to participate, you can stop at any time by using Azure PowerShell as follows:
1475-
1. Use the Disable-AzureDataCollection cmdlet to turn the feature Off. The cmdlet can be found in the AzureRM.Profile module
1476-
To disable data collection: PS &gt; Disable-AzureDataCollection
1471+
<data name="ARMDataCollectionMessage" xml:space="preserve">
1472+
<value>Azure PowerShell collects usage data in order to improve your experience.
1473+
The data is anonymous and does not include commandline argument values.
1474+
The data is collected by Microsoft.
14771475

1478-
If you choose to not participate, you can enable at any time by using Azure PowerShell as follows:
1479-
1. Use the Enable-AzureDataCollection cmdlet to turn the feature On. The cmdlet can be found in the AzureRM.Profile module
1480-
To enable data collection: PS &gt; Enable-AzureDataCollection
1481-
1482-
Select Y to enable data collection [Y/N]:</value>
1476+
Use the Disable-AzureRmDataCollection cmdlet to turn the feature Off. The cmdlet can be found in the AzureRM.Profile module. To disable data collection: PS &gt; Disable-AzureRmDataCollection.
1477+
Use the Enable-AzureRmDataCollection cmdlet to turn the feature On. The cmdlet can be found in the AzureRM.Profile module. To enable data collection: PS &gt; Enable-AzureRmDataCollection.</value>
14831478
</data>
14841479
<data name="DataCollectionActivity" xml:space="preserve">
14851480
<value>Microsoft Azure PowerShell Data Collection Confirmation</value>
@@ -1586,4 +1581,12 @@ Select Y to enable data collection [Y/N]:</value>
15861581
<data name="x86InProgramFiles" xml:space="preserve">
15871582
<value>(x86)</value>
15881583
</data>
1584+
<data name="RDFEDataCollectionMessage" xml:space="preserve">
1585+
<value>Azure PowerShell collects usage data in order to improve your experience.
1586+
The data is anonymous and does not include commandline argument values.
1587+
The data is collected by Microsoft.
1588+
1589+
Use the Disable-AzureDataCollection cmdlet to turn the feature Off. The cmdlet can be found in the Azure module. To disable data collection: PS &gt; Disable-AzureDataCollection.
1590+
Use the Enable-AzureDataCollection cmdlet to turn the feature On. The cmdlet can be found in the Azure module. To enable data collection: PS &gt; Enable-AzureDataCollection.</value>
1591+
</data>
15891592
</root>

src/ResourceManager/AnalysisServices/Commands.AnalysisServices.Dataplane/Commands/AddAzureASAccount.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ protected override void SaveDataCollectionProfile()
9090
// No data collection for this commandlet
9191
}
9292

93-
protected override void PromptForDataCollectionProfileIfNotExists()
93+
protected override void SetDataCollectionProfileIfNotExists()
9494
{
9595
// No data collection for this commandlet
9696
}

src/ResourceManager/AnalysisServices/Commands.AnalysisServices.Dataplane/Commands/Export-AzureAsInstanceLog.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ protected override void SaveDataCollectionProfile()
8585
// No data collection for this commandlet
8686
}
8787

88-
protected override void PromptForDataCollectionProfileIfNotExists()
88+
protected override void SetDataCollectionProfileIfNotExists()
8989
{
9090
// No data collection for this commandlet
9191
}

src/ResourceManager/AnalysisServices/Commands.AnalysisServices.Dataplane/Commands/Restart-AzureAsInstance.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ protected override void SaveDataCollectionProfile()
7676
// No data collection for this commandlet
7777
}
7878

79-
protected override void PromptForDataCollectionProfileIfNotExists()
79+
protected override void SetDataCollectionProfileIfNotExists()
8080
{
8181
// No data collection for this commandlet
8282
}

src/ResourceManager/Common/Commands.ResourceManager.Common/AzureRMCmdlet.cs

Lines changed: 7 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -182,46 +182,19 @@ protected override void SaveDataCollectionProfile()
182182
WriteWarning(string.Format(Resources.DataCollectionSaveFileInformation, fileFullPath));
183183
}
184184

185-
protected override void PromptForDataCollectionProfileIfNotExists()
185+
protected override void SetDataCollectionProfileIfNotExists()
186186
{
187-
// Initialize it from the environment variable or profile file.
188187
InitializeDataCollectionProfile();
189188

190-
if (!_dataCollectionProfile.EnableAzureDataCollection.HasValue && CheckIfInteractive())
189+
if (_dataCollectionProfile.EnableAzureDataCollection.HasValue)
191190
{
192-
WriteWarning(Resources.DataCollectionPrompt);
193-
194-
const double timeToWaitInSeconds = 60;
195-
var status = string.Format(Resources.DataCollectionConfirmTime, timeToWaitInSeconds);
196-
ProgressRecord record = new ProgressRecord(0, Resources.DataCollectionActivity, status);
197-
198-
var startTime = DateTime.Now;
199-
var endTime = DateTime.Now;
200-
double elapsedSeconds = 0;
201-
202-
while (!this.Host.UI.RawUI.KeyAvailable && elapsedSeconds < timeToWaitInSeconds)
203-
{
204-
Thread.Sleep(TimeSpan.FromMilliseconds(10));
205-
endTime = DateTime.Now;
206-
207-
elapsedSeconds = (endTime - startTime).TotalSeconds;
208-
record.PercentComplete = ((int)elapsedSeconds * 100 / (int)timeToWaitInSeconds);
209-
WriteProgress(record);
210-
}
211-
212-
bool enabled = false;
213-
if (this.Host.UI.RawUI.KeyAvailable)
214-
{
215-
KeyInfo keyInfo = this.Host.UI.RawUI.ReadKey(ReadKeyOptions.NoEcho | ReadKeyOptions.AllowCtrlC | ReadKeyOptions.IncludeKeyDown);
216-
enabled = (keyInfo.Character == 'Y' || keyInfo.Character == 'y');
217-
}
218-
219-
_dataCollectionProfile.EnableAzureDataCollection = enabled;
191+
return;
192+
}
220193

221-
WriteWarning(enabled ? Resources.DataCollectionConfirmYes : Resources.DataCollectionConfirmNo);
194+
WriteWarning(Resources.ARMDataCollectionMessage);
222195

223-
SaveDataCollectionProfile();
224-
}
196+
_dataCollectionProfile.EnableAzureDataCollection = true;
197+
SaveDataCollectionProfile();
225198
}
226199

227200
protected override void InitializeQosEvent()

0 commit comments

Comments
 (0)