Austin Agile DevOps

DevOps in the Cloud
posts - 66 , comments - 7 , trackbacks - 0

Tuesday, January 26, 2016

PowerShell Grant-EC2SecurityGroupIngress to All Traffic using AWS Source Security Group

I really had to dig for this, but it’s quite simple:

$natSG = Get-EC2SecurityGroup -Region $env:AWS_DEFAULT_REGION | ?{$_.Description -eq 'my NAT security group description' -and $_.VpcId -eq $vpcId }
$natSgGroupId = $natSG.GroupId
$defaultSG = Get-EC2SecurityGroup -Region $env:AWS_DEFAULT_REGION | ?{$_.Description -eq 'default VPC security group' -and $_.VpcId -eq $vpcId }
$sourceGroup = New-Object Amazon.EC2.Model.UserIdGroupPair
$sourceGroup.GroupId = $defaultSG.GroupId
$newIpRule = New-Object Amazon.EC2.Model.IpPermission -Property @{IpProtocol='-1'; FromPort='0'; ToPort='65535'; IpRanges='0.0.0.0/0'; UserIdGroupPair=$sourceGroup}
Grant-EC2SecurityGroupIngress -GroupId $natSgGroupId -IpPermission $newIpRule

Posted On Tuesday, January 26, 2016 9:52 AM | Comments (0) |

Tuesday, December 2, 2014

Wanna use Firefox on the TFS web frontend?

TFS uses a version of NTLM over unsecure HTTP and Firefox doesn't want to allow this by default. Of course, Firefox doesn't tell you it's forbidding something; instead it just acts like you got a 403.

Here's how to fix it so you can use FF on TFS:

  1. In your address bar, go to "about:config"
  2. You should get a little search bar and a giant list of properties. In the search bar, type "ntlm"
  3. Look for the property "network.negotiate-auth.allow-insecure-ntlm-v1" and double-click the "false" in the Value column. It should boldface and turn to "true". The boldface indicates a user-set property.
  4. Restart FF and you're good to go.

Posted On Tuesday, December 2, 2014 11:55 AM | Comments (0) |

Tuesday, September 30, 2014

Microsoft.WITDataStore.dll not found: NuGet NuSpec References

I ported my TFS API code to  use the V12 (2013) assemblies. I then built and created a NuGet package of the TFS API Lib and installed it in an application. Immediately that application build failed because the Microsoft.WITDataStore.dll assmebly was missing from my TFS API NuGet package. 

I found that by default, when the reference tag is not used at all, NuGet adds all files included in the lib folder as references.  I needed the Microsoft.WITDataStore.dll in the package lib folder, but not added as as a reference (this fails).

The solution was to update my NuSpec file to explicitly mark the files I wanted added as references to the project.

<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
    <metadata>
      <id>ALM.Tools.TfsApiLib</id>
      <version>0.0.0.0</version>
      <authors>Bob Hardister</authors>
      <description>A set of methods to get and set information in TFS 2013</description>
      <summary>Library of TFS API Methods.</summary>
      <dependencies>
        <dependency id="RavenDB.Client" version="2.5.2910" />
      </dependencies>
      <references>
        <reference file="Microsoft.TeamFoundation.Build.Activities.dll" />
        <reference file="Microsoft.TeamFoundation.Build.Client.dll" />
        <reference file="Microsoft.TeamFoundation.Build.Common.dll" />
        <reference file="Microsoft.TeamFoundation.Build.Workflow.dll" />
        <reference file="Microsoft.TeamFoundation.Client.dll" />
        <reference file="Microsoft.TeamFoundation.Common.dll" />
        <reference file="Microsoft.TeamFoundation.VersionControl.Client.dll" />
        <reference file="Microsoft.TeamFoundation.VersionControl.Common.dll" />
        <reference file="Microsoft.TeamFoundation.WorkItemTracking.Client.dll" />
        <reference file="Microsoft.TeamFoundation.WorkItemTracking.Common.dll" />
        <reference file="Microsoft.TeamFoundation.WorkItemTracking.Proxy.dll" />
        <reference file="NLog.dll" />
        <reference file="TfsApiLib.Tool.Methods.dll" />
        <reference file="TfsApiLib.Tool.RunProcess.dll" />
      </references>
    </metadata>
    <files>
      <file src="bin\$configuration$\Microsoft.TeamFoundation.*" target="lib\net45" />
      <file src="bin\$configuration$\Microsoft.WITDataStore.dll" target="lib\net45" />
      <file src="bin\$configuration$\NLog.dll" target="lib\net45\NLog.dll" />
      <file src="bin\$configuration$\TfsApiLib.Tool.*" target="lib\net45" />
    </files>
</package>

Posted On Tuesday, September 30, 2014 8:41 AM | Comments (0) |

Friday, September 12, 2014

TFS Git Delete Remote Branch from Server

You can delete a published branch from Visual Studio, but to remove it from the server use the this git statement from the command prompt of the local repo:

C:\_s\Git\myRepo>git push origin --delete myBranch

Posted On Friday, September 12, 2014 6:36 PM | Comments (0) |

Friday, September 5, 2014

Team Explorer Everywhere Command Line Client on a Mac

I was surprised at the dearth of information on this. Here’s the whole enchilada. I did not have to enter user or password information for the TF commands. This could be because my Mac account and password is identical to the Windows AD account and password. Use TF help to get a full listing of commands and TF Help [command] for details on each command.

  1. Download TEE-CLC on your Mac and unzip/move the TEE-CLC-x.x.x folder under your Applications folder.
  2. Open the Terminal command line on you Mac (search for Terminal)
  3. To see the current execution path on your Mac:
    • echo $PATH
  4. Enter the following to add the TEE-CLC to you path:
    • export PATH=$PATH:/Applications/{TEE CLC folder name}
    • example: export PATH=$PATH:/Applications/TEE-CLC-11.0.0
  5. Enter the echo command again to verify the TEE CLC folder has been added to the path
  6. Install the Java JDK (installing just the run time is  not sufficient)
  7. You should be able to execute the TF command from the Terminal window once the Java JDK install has completed
  8. Create a folder to store your TFS source control files. I used \Documents\_s\MyCollection
  9. Accept the TCC license by executing:
    • tf eula
  10. Create the workspace:
    • tf workspace -new -collection:{url} -location:server {workspace name}
  11. Create the workspace mapping
    • tf  workfold -map -collection:{url} -workspace:{workspace name} '$/' '/Users/bob_hardister/Documents/_s/MyCollection'
  12. Navigate to your local workspace folder in the Terminal window to run TF Get and other workspace centric commands
  13. A Get command would then be
    • tf get -r  '$/…desried TFS server location to pull from'

Posted On Friday, September 5, 2014 11:58 AM | Comments (0) |

Friday, July 25, 2014

Move TFS 2013 Git Repo to a Different Team Project

1. Go to the target team project admin site

2. Create the new repo on the TFS server (with the same name as the source repo except under the target team project)

3. Go to the target team project site and display the empty repo. Note the new repo remote url

4. Open Visual Studio 2013 team explorer connect tab (Update 2 or >) and connect to the remote source repo

5. Clone the repo under the new team project or other location

6. Right click on the new (cloned) local repo and click Open Command Prompt

7. Copy the new remote url of the target team project repo (see #3 above)

8. Execute the following command in the command prompt:

[new local repo location]>git remote set-url origin [new remote url]

9. Right click on the new local repo in the Visual Studio 2013 team explorer connect tab

10. Click Open

11. Click "Unsynced Commits"

12. Click the "Sync" button to push the local repo to the remote

13. Go to the remote repo site and refresh to display the code just pushed from the local repo

Posted On Friday, July 25, 2014 12:34 PM | Comments (0) |

Tuesday, July 8, 2014

TFS 2013 Build Process Template – Change the “AutomatedTest” Argument Default Value

It should be simple, but due to the length of the string, the syntax was not obvious. The out-of-the-box default is as follows. Note the backslash escape character and stick to the syntax:

{New Microsoft.TeamFoundation.Build.Common.BuildParameter(" { ""AssemblyFileSpec"": ""**\\*test*.dll;**\\*test*.appx"", ""RunSettingsFileName"": null, ""TestCaseFilter"": """", ""RunSettingsForTestRun"": { ""ServerRunSettingsFile"": """", ""TypeRunSettings"": ""Default"", ""HasRunSettingsFile"": false }, ""HasRunSettingsFile"": false, ""HasTestCaseFilter"": false, ""ExecutionPlatform"": ""X86"", ""FailBuildOnFailure"": false, ""RunName"": """" } ")}

If you remove the values to expose the syntax you get:

{New Microsoft.TeamFoundation.Build.Common.BuildParameter("")}

To add another “test” to the template use this:

{New Microsoft.TeamFoundation.Build.Common.BuildParameter(""), 
New Microsoft.TeamFoundation.Build.Common.BuildParameter("")}

and just provide the desired values. Here’s what I ended up with:

{New Microsoft.TeamFoundation.Build.Common.BuildParameter(" { ""AssemblyFileSpec"": ""*UnitTests\\*Tests.dll"", ""RunSettingsFileName"": null, ""TestCaseFilter"": """", ""RunSettingsForTestRun"": { ""ServerRunSettingsFile"": """", ""TypeRunSettings"": ""Default"", ""HasRunSettingsFile"": false }, ""HasRunSettingsFile"": false, ""HasTestCaseFilter"": false, ""ExecutionPlatform"": ""X64"", ""FailBuildOnFailure"": false, ""RunName"": ""Unit"" } "), New Microsoft.TeamFoundation.Build.Common.BuildParameter(" { ""AssemblyFileSpec"": ""*IntegrationTests\\*Tests.dll"", ""RunSettingsFileName"": null, ""TestCaseFilter"": """", ""RunSettingsForTestRun"": { ""ServerRunSettingsFile"": """", ""TypeRunSettings"": ""Default"", ""HasRunSettingsFile"": false }, ""HasRunSettingsFile"": false, ""HasTestCaseFilter"": false, ""ExecutionPlatform"": ""X64"", ""FailBuildOnFailure"": false, ""RunName"": ""Integration"" } ")}

Posted On Tuesday, July 8, 2014 12:56 PM | Comments (0) |

Nuget Push to Klondike Requires Packages Appended to Source and SetApiKey URL

When we upgraded to NuGet 2.8 our PUSH command  starting failing.  The first fix was to appended “packages” to the source URL string like this:

myFeed.com:8080/api/packages

We use the SetApiKey command on our server so we don’t have to explicitly include the API key itself in the push command. After making the change above we had issues with the PUSH command not finding the API key. To fix this, we appended “packages” to the source argument of the SetApiKey command like this:

nuget setApiKey myApiKey -Source myFeed.com:8080/api/packages

Everything then worked fine as before.

Posted On Tuesday, July 8, 2014 10:47 AM | Comments (0) |

Wednesday, June 25, 2014

Get the Last Build By Build Number with Visual Studio ALM Team Foundation Server API

Here is a handy TFS 2013 build activity for getting the last build by build number filter. In this case:

  • We get the 4th version node number: we call it the revision number
  • We use semantic versioning and some of our branches are “version named” i.e. 1.4.10
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Activities;
using System.IO;
using System.Text.RegularExpressions;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Build.Workflow;

namespace Alm.BuildActivities
{
[BuildActivity(HostEnvironmentOption.Agent)]
    public sealed class GetVersionNamedBranchLastRevisionNumber : CodeActivity
    {
        #region arguments
        [RequiredArgument]
        public InArgument<string> BuildDefinitionName { get; set; }
        public InArgument<string> CollectionUrl { get; set; }
        public InArgument<string> ProjectName { get; set; }
        public InArgument<string> VersionNamedBranch { get; set; }
        public OutArgument<int> CurrentRevisionNumber { get; set; }
        #endregion

        protected override void Execute(CodeActivityContext context)
        {
            #region initialize fields
            context.SetValue(this.CurrentRevisionNumber, 0);
            string buildDefinitionName = context.GetValue(this.BuildDefinitionName);
            string collectionUrl = context.GetValue(this.CollectionUrl);
            string projectName = context.GetValue(this.ProjectName);
            string versionNamedBranch = context.GetValue(this.VersionNamedBranch);
            int currentRevisionNumber = 0;
            #endregion

            try
            {
                TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(new Uri(collectionUrl));
                tpc.EnsureAuthenticated();

                if (!(tpc == null))
                {
                    var bs = tpc.GetService<IBuildServer>();
                    var buildDefSpec = bs.CreateBuildDefinitionSpec(projectName, buildDefinitionName);
                    buildDefSpec.PropertyNameFilters.Add("Name");
                    buildDefSpec.Options = QueryOptions.None;
                    var buildDef = bs.QueryBuildDefinitions(buildDefSpec).Definitions.FirstOrDefault();

                    var buildSpec = bs.CreateBuildDetailSpec(buildDef);
                    //gets only "stable builds" of the version named branch
                    buildSpec.BuildNumber = string.Format("*_{0}.?", versionNamedBranch); 
                    buildSpec.QueryDeletedOption = QueryDeletedOption.IncludeDeleted;
                    buildSpec.MaxBuildsPerDefinition = 1;
                    //gets last stable build of the version named branch
                    buildSpec.QueryOrder = BuildQueryOrder.StartTimeDescending; 

                    var buildQuery = bs.QueryBuilds(buildSpec).Builds.FirstOrDefault();

                    if (buildQuery == null)
                    {
                        currentRevisionNumber = 0; //there aren no stable builds of this version named branch
                        context.SetValue(this.CurrentRevisionNumber, currentRevisionNumber);
                    }
                    else
                    {
                        var lastStableBuildNumber = buildQuery.BuildNumber;
                        string currentRevisionNumberString = lastStableBuildNumber
                            .Substring(lastStableBuildNumber.LastIndexOf(".") + 1);
                        bool result = Int32.TryParse(currentRevisionNumberString, out currentRevisionNumber);
                        if (result)
                        {
                            context.SetValue(this.CurrentRevisionNumber, currentRevisionNumber); 
                        }
                        else
                        {
                            string text = "ERROR: unable to parse to int the currentRevisionNumberString value:";
                            throw new Exception(string.Format("{0} {1}.", text, currentRevisionNumberString));
                        }
                    }
                }
                else
                {
                    throw new Exception("ERROR: unable to connect to TFS collection");
                }
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("ERROR. Exception message: {0}", ex.Message));
            }
        }
    }
}

Posted On Wednesday, June 25, 2014 9:15 AM | Comments (0) |

Monday, April 28, 2014

Delete Build Drop Locations Some Number of Days Old

We don’t need to keep our drop folders after a week. Here some code to accomplish that.

[TestMethod]
public void SetDeleteBuildDropFolder()
{
    //method parms
    string collectionUrl = "http://myCollectionUrl";
    string projectName = "myTeamProjectName";
    var buildDefinitionNames = new List<string>();
    buildDefinitionNames.Add("myBuildDefinitionName");
    
    var fromDate = DateTime.Now.AddDays(-8);
    
    //execute method
    var buildsDropFoldersDeleted = tfsApi.SetDeleteBuildDropFolder(collectionUrl, projectName, buildDefinitionNames, fromDate);

    //evaluate result
    Assert.IsNotNull(buildsDropFoldersDeleted);
}
        
public Dictionary<string, string> SetDeleteBuildDropFolder(string collectionUrl, string projectName, 
List<string> buildDefinitionNames, DateTime fromDateTime) { var buildsDropFoldersDeleted = new Dictionary<string, string>(); try { TfsTeamProjectCollection tpc = GetCollection(collectionUrl); if (!(tpc == null)) { var bs = tpc.GetService<IBuildServer>(); foreach (var buildDefName in buildDefinitionNames) { var buildSpec = bs.CreateBuildDetailSpec(projectName, buildDefName); buildSpec.QueryOptions = QueryOptions.None; buildSpec.InformationTypes = null; buildSpec.MaxBuildsPerDefinition = 100; buildSpec.QueryOrder = BuildQueryOrder.StartTimeDescending; buildSpec.QueryDeletedOption = QueryDeletedOption.ExcludeDeleted; if (buildSpec != null) { var buildsDrops = bs.QueryBuilds(buildSpec).Builds.Where(x => x.FinishTime < fromDate)
.Select(y => new { y.Uri, y.DropLocation }); foreach (var build in buildsDrops) { if (Directory.Exists(build.DropLocation)) { try { var bSpec = bs.CreateBuildDetailSpec(projectName, buildDefName); bSpec.QueryOptions = QueryOptions.None; bSpec.InformationTypes = null; bSpec.QueryDeletedOption = QueryDeletedOption.ExcludeDeleted; //Using the build service you can delete multiple build drop folders at the same time //var targetBuild = bs.QueryBuilds(bSpec).Builds.Where(b => b.Uri == build.Uri).ToArray(); //bs.DeleteBuilds(targetBuild, DeleteOptions.DropLocation); //Here I'm only deleting a single build drop folder at a time var targetBuild = bs.QueryBuilds(bSpec).Builds.Where(b => b.Uri == build.Uri).FirstOrDefault(); if (targetBuild.KeepForever) { targetBuild.KeepForever = false; targetBuild.Save(); } targetBuild.Delete(DeleteOptions.DropLocation); buildsDropFoldersDeleted.Add(targetBuild.BuildNumber, build.DropLocation); } catch (Microsoft.TeamFoundation.Build.Client.BuildDefinitionNotFoundException) { //build not found } } } } else { return null; } } return buildsDropFoldersDeleted; } else { return null; } } catch (Exception ex) { return null; } }

Posted On Monday, April 28, 2014 9:04 AM | Comments (0) |

Powered by: