Well, it has been over a week since I picked up my guitar, and I figured it was time to pull it out. Here is the result of that:
Figured too since I am growing the Paul McCartney beard out, I might as well try to sing like him. 🙂
Well, it has been over a week since I picked up my guitar, and I figured it was time to pull it out. Here is the result of that:
Figured too since I am growing the Paul McCartney beard out, I might as well try to sing like him. 🙂
If you want to create a calculated measure in SSAS (SQL Server Analysis Services) that will always get the value for yesterday, this is what I have come up with:
CREATE MEMBER CURRENTCUBE.[MEASURES].[My Yesterday Measure]
AS (StrToMember(‘[Time].[Calendar Date].&[‘+ VBA!Format(vba!dateadd(“d”, -1, vba![date]()),’yyyy-MM-dd’) +’T00:00:00]’),[Measures].[My Cool Value]),
FORMAT_STRING = “$#,##0.000”,
VISIBLE = 1 ;
What is really cool is you can test this before you even make the measure, using an MDX query:
WITH
MEMBER Measures.[Yesterday Measure Test1]
AS ([Time].[Calendar Date].&[2007-07-09T00:00:00],[Measures].[My Cool Value])
MEMBER Measures.[Yesterday Measure Test2]
AS (StrToMember(‘[Time].[Calendar Date].&[‘+ VBA!Format(vba!dateadd(“d”, -1, vba![date]()),’yyyy-MM-dd’) +’T00:00:00]’),[Measures].[My Cool Value]),FORMAT_STRING = “$#,##0.000”
SELECT {
Measures.[Yesterday Measure Test1]
,Measures.[Yesterday Measure Test2]
} ON COLUMNS
FROM [My Cube]
and now you can take that calculated measure and tweak for any days back (30, etc)
Cool! 🙂
Usually, in a company, there is a “development” department and a “IT” department, and usually the departments don’t really work together. Development is focused on delivering business value through coding applications for end users or B2B clients. IT is busy making sure the corporate network is humming along, and that other internal issues related to technology in general are taken care of.
In my experience, I like to jump the threshold between the two departments. I started out working Helpdesk (IT Dept) and coded in the time I had free, eventually starting/breaking into the Development side. But, my passion for internal IT functions didn’t slow. Some of the guys I worked with in the IT Department always wanted applications to do specific things for OUR network, things you can’t buy, or things that you can buy a generic application for way to much money and it won’t work exactly how you want it to. That is where developers and IT can actually work together and bridge that gap.
This post is about backing up configurations on Cisco routers using .NET (C#). Now, most developers programming away on business applications really don’t care about the routers inside their company. They know they are there, might know somewhat how they work, and as long as they work, its fine – that is what IT is all about. But on the other hand, the Network Administrator really cares about Cisco routers. He dreams about them. Names his kid Cisco, or Switch.
Now, the network admin can login to all his routers, and run some commands to backup his configs. The most usual way to do this is to send the config to a TFTP server. Now, if they want a backup once a month, and they have one router, well then great, a manual solution is fine. The network is probably not big or complex and the network admin needs something to do. In most cases though, they would want to back up their routers daily, and they might have multiple routers.
In this scenario, let the network admin set up the TFTP server. Those are abundant and easy to find, easy to setup. What we are concerned with from a development standpoint is actually logging into the router, running commands to backup the config (to the TFTP server) and getting out.
Now, a few things are needed from your network admin. First, you are going to need the IP addresses of all the routers. Next, you want to make sure that they have one user on all the routers with the same password that you can use just for this backup program. There are multiple ways I am sure they can do this, and since I am not a network guru, leave that to them – they will throw out terms like RADIUS, etc, but it should be easy for them. Next, you need them to make sure that all routers are set up the same, as far as the way they use “enable” commands, etc.
The first thing you want to do is take that information from your network admin, and then test each one manually. Telnet (or SSH if you can get that working) using the IP, login with the user and password, and then run the enable command, and look at the strings that are responsed back to you. Every router has a name like
company-router-123>
where the > is the prompt. You need to jot down this name to go along with the IP address. Now you can get fancy later and have your network admin set that name up in DNS and then you can just have a list of names, but start with IP addresses first.
Now, here comes the developing part. A long long time ago, right when .NET hit the airwaves, I created a class library called Winsock.Telnet so I could use it. Named it Winsock because I was a VB6 developer and I used the Winsock control to do telnets within my programs, so it just made sense. I still use this library today, and I do have the source code to it somewhere buried on a backup DVD or server in my apartment, and finding it would just be a wasted effort at this point, but the class library works, so that is what matters. I use this class library to do my telnets. (To do SSH I have used WeOnlyDo’s .net SSH Client – Chris Super blogs about how to run SSH on your network yet still use telnet for a specific purpose – such as this). You can get my Winsock library here.
Here is the guts of the main method to log a config from a Cisco router. Steps are easy. Connect, login, enable, run the TFTP command, send in the TFTP address, and a path , then exit. The second half is extra credit. I actually set up a SVN repo to the directory on the server that I TFTP the configs to, do a SVN diff, and if different, I email the changes to the network admin. But everything up the “exit” command would get you buy. The Sleep(1) function just waits for a second, which with telnet you need to do, so you don’t overrun your self. I have included the methods to do the SVN diff.
private static void LogRouterConfigTelnet(string deviceName, string ipAddress, string enablePassword)
{
_connectorTelnet = new WinsockTelnet.Winsock(ipAddress, 23, 60);
_connectorTelnet.Connect();
_connectorTelnet.WaitAndSend("Username:", _username);
_connectorTelnet.WaitAndSend("Password:", _password);
_connectorTelnet.WaitAndSend(deviceName + ">", "enable");
_connectorTelnet.WaitAndSend("Password:", enablePassword);
Sleep(1);
_connectorTelnet.SendAndWait("copy run tftp", "[]?");
_connectorTelnet.SendAndWait(_tftpAddress, "?");
_connectorTelnet.SendAndWait("routers/" + deviceName + "/" + _filename, deviceName + "#");
_connectorTelnet.SendMessage("exit");
_connectorTelnet.Disconnect();
// copy over svn copies, delete from root folder
File.Copy(@"C:TFTP-Rootrouters" + deviceName + @"" + _filename, @"c:tftp-sourcerouters" + deviceName + ".txt", true);
// do svn diff
string diff = SVNDiff(deviceName + ".txt");
if (!string.IsNullOrEmpty(diff))
{
System.Console.WriteLine(diff);
// if different, commit to svn, email diffs
SVNCommit(deviceName + ".txt");
EmailDiff(deviceName, diff.Replace(Environment.NewLine, "<br>").Replace("n", "<br>"));
}
}
private static string SVNDiff(string filename)
{
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = @"C:Program FilesSubversionbinsvn.exe";
psi.WorkingDirectory = @"C:tftp-sourceRouters";
psi.Arguments = String.Format("diff {0}", filename);
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
psi.CreateNoWindow = true;
Process p;
String output;
p = Process.Start(psi);
try
{
output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
}
finally
{
// shouldnt happen but lets play it safe
if (!p.HasExited)
{
p.Kill();
}
}
return output.Trim();
}
private static void SVNCommit(string filename)
{
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = @"C:Program FilesSubversionbinsvn.exe";
psi.WorkingDirectory = @"C:tftp-sourceRouters";
psi.Arguments = String.Format("commit -m "config changed" {0}", filename);
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
psi.CreateNoWindow = true;
Process p;
String output;
p = Process.Start(psi);
try
{
output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
}
finally
{
// shouldnt happen but lets play it safe
if (!p.HasExited)
{
p.Kill();
}
}
}
static void EmailDiff(string deviceName, string diff)
{
MailMessage msg = new MailMessage();
msg.To = "networkadmin@yourcompany.com";
msg.From = "ciscoconfig@yourcompany.com";
msg.Subject = "Cisco Config Changed - " + deviceName;
msg.Body = diff;
msg.BodyFormat = MailFormat.Html;
SmtpMail.SmtpServer = "yourmailserver";
try
{
SmtpMail.Send(msg);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
}
}
static void Sleep(int seconds)
{
System.Threading.Thread.Sleep(seconds * 1000);
}
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
So, you can see, taking a little time to create a small program to do this is not really tough. And your IT department will be happy. It will also give you a reason to use things in .NET that you might not use everyday, especially if you are a Web Programmer, and also you will learn a little more about IT things (routers, networks, etc).
Note: you can see the code isn’t the prettiest, and really doesn’t need to be. There is some duplication yeah, and some hardcoded paths. If you are worried, release a 2.0 version with all that in the App.Config and refactor out a couple of methods. Or if you get really good, create a library called Utils or something with all the common functions you are going to use, like for calling processes, etc.
Yeah, not good, especially if you are sunburnt (man, I think I got sun poisoning!!! – but it is finally getting better) – anyway’s it is HOT in PDX today. I guess it was 104 at 4PM, now its 4:30 and its 101. I had to go to Starbucks, since my apartment was more like a sauna than anything. No air conditioning, not really needed when it gets hot 2-3 days a year. By 11 PM I am sure it will be good, but supposed to be hot tomorrow to.
Might be a Starbucks day tomorrow too 🙂
Yesterday I got an invite to Pownce (http://pownce.com/ScaleOvenStove/). Pownce is the next thing from Kevin Rose, the founder of Digg. It is an application that works on the web and desktop. You can send messages, links, files to your friends and to public. It is kind of like twitter but with more options, and there is the desktop aspect.
The desktop app is written on top of AIR (Adobe Integrated Runtime) – which is in experimental beta right now, which kind of sucks, but yeah, it works. One thing that I really don’t like, is that you can’t minimize the app to the systray, its open, or closed. Doesn’t seem like their are many options in the app as well. Basically a suped up flash app that runs on your desktop.
I have some friends on there, that I invited, that really aren’t my friends (that is the way I got an invite) – I have a couple invites left if someone that I would actually send stuff to would like one.
This app reminds me of an app I started a while ago, PeTuPe – to share files and such with your friends (which maybe one day I will just make and complete it). Just another p2p app/IM client. I don’t see any real benefit at this point, but maybe something more will come out of it.
Since cutting cable, I have tried many different online TV programs. Democracy TV (soon to be Miro), TVTonic, Amazon Unbox, ITunes Video Store, Joost, etc. I finally got a beta invite to VeohTV the other day, and installed it Friday night. Since I am sunburned like crazy, I am holed up in my apartment anyway’s, so why not fool around with it.
It is the best online TV program I have used yet. First, it works with my Media Center remote. Second, it has all the shows from the major networks, the ones they have online. ABC, FOX, NBC, CBS, etc – you can watch the episodes they have online but through Veoh, which is a better interface.
They have an extensive list of other programs as well, short podcasts and small shows. DrinksTV.com as an example. (TVTonic does have a beer channel though :))
I am now watching Jericho (from CBS), all the episodes, which is pretty cool, and there is minimal advertising. One thing with all online TV networks/programs is this, and it is a huge pet peeve, the advertisements volume is usually WAY higher than the show, its just ridiculous, I just end up muting it then, what do they think?
I have noticed as well, as the major networks shows are different quality and different options. ABC/NBC seem good, CBS on the other hand, choppy, lower res, and harder to skip segments. FOX seems OK as well.
I recently redid my desktop computer with Vista Ultimate (with Media Center) and I have that directly hooked up to my TV, which I have never done before, and I really like the experience – the 360 has the extender, but direct connection is much better. I have decided that I will use my 360 for Video downloads from their marketplace, and for games, and forget the extender for now. If I had two TV’s in different rooms, then maybe it would be another story.
Flickr. Great online app, but uploading pictures through their website is pain at best. Other online sites have better uploading tools built right into their websites (MySpace, Facebook, etc). There is also the ability to tag your photos when you upload, but from what I have seen from all my friends photos, they aren’t tagging them correctly.
First, if you do any kind of serious uploading (more than 3-4 photos at a time), you want to download the Flickr Uploadr Tool onto your computer, then run it. What I have seen, in Windows XP, the Explorer Shell integration (you know, highlight one or more photos, right click, “Send to Flickr…”) always works, whereas on Vista, it seems to work off and on. You can either do the right click, or run the tool from the shortcut, and you should see a screen like this:
Now, you can either add more photos, remove photos, or click “Upload”
Here you can set tags (we will get to that later), add to a existing set, create a new set, and set the permissions. As far as permissions go, its all or none type thing. Usually I have a ton of photos from a day/weekend and some are private, some are public. What I do in this scenario is upload the public ones first (creating a set) then uploading the private ones after, adding to the set I just created, but making the pictures private.
Tags. Ok, Flickr’s tagging system is cool, but the biggest thing I have seen is people put tags for something with two or more words, but they put the tags wrong, so it shows up goofy on their pictures.
Here is an example. I just uploaded pictures from camping, and one of my tags was “Silver Falls State Park”. When I added the tag, I had the quotes around it, so the pictures have that whole phrase as a tag. If you leave off the quotes, the picture will have 4 tags: “Silver” “Falls” “State” “Park” – which doesn’t really make much sense. My pictures don’t have any silver in them 🙂
So, there you have it. The How To on uploading and tagging your Flickr uploads!
So, on the way to Sauvie Island, we stopped at a 7-Eleven to get a parking permit for the day, and even though the whole store wasn’t branded a Kwik-E-Mart, everything inside was “Simpsonized”, I just had to pick up a sixer of Buzz Cola. Not sure if I am going to drink it yet or not though 🙂
We went camping this 3rd, 4th, 5th of July to Silver Falls State Park, which was a nice getaway from the city, considering I live right on a busy road. There are 10 waterfalls around the trails, and we hit up 7 of them, pictures on Flickr here: http://flickr.com/photos/scaleovenstove/sets/72157600684621176/
After driving back, we went to Sauvie Island, to the beach, Collin’s Beach I think. Was interesting. I got totally sunburnt, which today hurts like crazy.