-Поиск по дневнику

Поиск сообщений в rss_thedaily_wtf

 -Подписка по e-mail

 

 -Постоянные читатели

 -Статистика

Статистика LiveInternet.ru: показано количество хитов и посетителей
Создан: 06.04.2008
Записей:
Комментариев:
Написано: 0

The Daily WTF





Curious Perversions in Information Technology


Добавить любой RSS - источник (включая журнал LiveJournal) в свою ленту друзей вы можете на странице синдикации.

Исходная информация - http://thedailywtf.com/.
Данный дневник сформирован из открытого RSS-источника по адресу http://syndication.thedailywtf.com/thedailywtf, и дополняется в соответствии с дополнением данного источника. Он может не соответствовать содержимому оригинальной страницы. Трансляция создана автоматически по запросу читателей этой RSS ленты.
По всем вопросам о работе данного сервиса обращаться со страницы контактной информации.

[Обновить трансляцию]

I Hate the Lord of the Rings

Четверг, 28 Января 2016 г. 14:00 + в цитатник

Today, we're breaking out something a little different. I put this together more for fun than anything else, and we piloted it around in the Side Bar, along with a few other shares.

After some feedback, we're happy to bring this to the front page, and we plan to produce more of videos in this vein as a recurring periodic feature.

Sometimes, it feels like getting our work done is an epic struggle, suitable for retelling by the greatest of bards. And you know what? You're absolutely right. IT is an epic quest- and that's why I can't stand the Lord of the Rings. It's too much like work.



[Advertisement] Release! is a light card game about software and the people who make it. Play with 2-5 people, or up to 10 with two copies - only $9.95 shipped!

http://thedailywtf.com/articles/i-hate-the-lord-of-the-rings


Метки:  

CodeSOD: Utter Filth

Среда, 27 Января 2016 г. 14:30 + в цитатник

Terrell inherited some database stored procedures. Like all good, Enterprisey stored procedures, it was written in PL/SQL. Unlike most Enterprisey procedures, it had a clear purpose: to clean your dirty inputs.

The actual problem: based on user input, the PL/SQL code needed to write a temporary file to the filesystem. Since user input is full of filthy, illicit characters, this procedure needs to clean them up.

PROCEDURE p_clean_name (
      p_file_name             IN       VARCHAR2,
      p_file_name_end         OUT      VARCHAR2
   )
---------------------------------------------------------------------------------------------------
-- Purpose: Clean the file name removing all dirty characters
----------------------------------------------------------------------------------------------------
   IS
      l_function_name   VARCHAR2 (64) := 'p_clean_name';
   BEGIN
      p_file_name_end :=
         REPLACE
            (REPLACE
                (REPLACE
                    (REPLACE
                        (REPLACE
                            (REPLACE
                                (REPLACE
                                    (REPLACE
                                        (REPLACE
                                            (REPLACE
                                                (REPLACE
                                                    (REPLACE
                                                        (REPLACE
                                                            (REPLACE
                                                                (REPLACE
                                                                    (REPLACE
                                                                        (REPLACE
                                                                            (REPLACE
                                                                                (REPLACE
                                                                                    (REPLACE
                                                                                        (REPLACE
                                                                                            (REPLACE
                                                                                                (REPLACE
                                                                                                    (REPLACE
                                                                                                        (REPLACE
                                                                                                            (REPLACE
                                                                                                                (REPLACE
                                                                                                                    (REPLACE
                                                                                                                        (REPLACE
                                                                                                                            (REPLACE
                                                                                                                                (REPLACE
                                                                                                                                    (REPLACE
                                                                                                                                        (TRIM
                                                                                                                                            (p_file_name
                                                                                                                                            ),
                                                                                                                                         '/',
                                                                                                                                         '_'
                                                                                                                                        ),
                                                                                                                                     '*',
                                                                                                                                     '_'
                                                                                                                                    ),
                                                                                                                                 '%',
                                                                                                                                 '_'
                                                                                                                                ),
                                                                                                                             '`u',
                                                                                                                             '_'
                                                                                                                            ),
                                                                                                                         '`o',
                                                                                                                         '_'
                                                                                                                        ),
                                                                                                                     '`a',
                                                                                                                     '_'
                                                                                                                    ),
                                                                                                                 '`e',
                                                                                                                 '_'
                                                                                                                ),
                                                                                                             '`u',
                                                                                                             '_'
                                                                                                            ),
                                                                                                         '`i',
                                                                                                         '_'
                                                                                                        ),
                                                                                                     ''e',
                                                                                                     '_'
                                                                                                    ),
                                                                                                 '°',
                                                                                                 '_'
                                                                                                ),
                                                                                             '$',
                                                                                             '_'
                                                                                            ),
                                                                                         'lb',
                                                                                         '_'
                                                                                        ),
                                                                                     '&',
                                                                                     '_'
                                                                                    ),
                                                                                 '?',
                                                                                 '_'
                                                                                ),
                                                                             '§',
                                                                             '_'
                                                                            ),
                                                                         '^',
                                                                         '_'
                                                                        ),
                                                                     '(',
                                                                     '_'
                                                                    ),
                                                                 ')',
                                                                 '_'
                                                                ),
                                                             '\',
                                                             '_'
                                                            ),
                                                         '#',
                                                         '_'
                                                        ),
                                                     '+',
                                                     '_'
                                                    ),
                                                 '[',
                                                 '_'
                                                ),
                                             ']',
                                             '_'
                                            ),
                                         ';',
                                         '_'
                                        ),
                                     ':',
                                     '_'
                                    ),
                                 '@',
                                 '_'
                                ),
                             'c',
                             '_'
                            ),
                         '<',
                         '_'
                        ),
                     '>',
                     '_'
                    ),
                 '.',
                 '_'
                ),
             ' ',
             '_'
            );
   EXCEPTION
      WHEN OTHERS
      THEN
         p_handle_log ('X',
                      SQLCODE ||'-'|| SQLERRM || '- ' || DBMS_UTILITY.format_error_backtrace(),
                      l_function_name,
                      null,
                      null
                     );     
   END;

Well, something is dirty in here.

[Advertisement] BuildMaster is more than just an automation tool: it brings together the people, process, and practices that allow teams to deliver software rapidly, reliably, and responsibly. And it's incredibly easy to get started; download now and use the built-in tutorials and wizards to get your builds and/or deploys automated!

http://thedailywtf.com/articles/utter-filth


Метки:  

The Productivity Leader

Вторник, 26 Января 2016 г. 14:30 + в цитатник

Jane took a job at a big financials company. The pay and the benefits were the first draw, but she was really sucked in by the visions of building analytics and juggling billions of dollars with cutting edge data mangling techniques. Big data came up in the interview many times, along with cloud.

The first cold blast of reality was when she was given her developer desktop: a Windows XP box with 4GB of RAM and a CPU that could get lapped by the processor in a BlackBerry. Oh, is this just a dumb terminal I use to connect to your cloud? Jane asked.

Productivity versus hours worked, showing a steady decline year over year.

No, her boss said. This is your work computer. As it turned out, Jane had misunderstood the interview- they had asked about big data and cloud because those were buzzwords that they might be interested in, someday. Today, there were only two applications Jane needed to worry about.

Corporate policy dictated that her computer must be shutdown every night. Each day, when Jane came into work, she would start it up. After a few cups of coffee, it would eventually chug to life, at which point she could fire up the two required applications: Outlook and SameTime.

Jane wasnt officially considered at work unless her boss saw her logged into SameTime. In fact, as Jane quickly discovered, the rapid path to promotion was to leave yourself logged into SameTime for twelve hours a day. Even if you never committed a single line of code, that was enough to make you a productivity leader, like Chad.

Chad was the productivity leader on their team. He had committed just one, one-line-bug-fix in his entire time at the company, but he was always online. Once or twice a week, Janes boss would swing by, Hey, you should really talk to Chad, hed say, Ive told him to mentor you, and hes got exactly what it takes to succeed here.

Jane didnt, because sometimes, Jane would try and write software. The emphasis was on try. The first step was to launch Eclipse. The only version she was allowed to use was so ancient that it predated the Jovian naming convention. Waiting for this to start was enough time for Jane to exhaust her phones data plan streaming Netflix.

Finally, Jane could actually look at some Java code. Running it was a bit more of a challenge- it meant launching a local WebLogic server, connecting with Firefox, and then trying to replicate and fix bugs. Between the ancient hardware, the ancient OS, the ancient Eclipse, a version of WebLogic that was so old that it could be featured on Antiques Roadshow, and code that was intimately tied to the database server, it could take hours to make it through a single edit-compile-debug cycle.

It was an uphill battle against processes and attitudes that were frozen in 1983, but each Day, Jane went home, confident that she had made the code better. In a small way. A very small way.

One day, Janes boss transferred to a different team and vaulted up a pay-grade in the process. Their productivity leader, Chad, was sucked into the vacancy in his wake. On his first day, Chad called a meeting.

Now, I know were a little behind the times here, Chad said.

Jane nodded like a bobblehead.

And I know that we spend more time sitting and waiting than doing any real work, he continued. But Ive been talking to management, and theyre really enthusiastic about modernization. So be ready for some big changes in the near future, and not to spoil anything- but the word cloud is going to feature big in our plans. After the announcement, Chad asked Jane to stay behind. Once they were alone, he said, Ive been meaning to talk to you about the amount of time youre logged into SameTime…

That was the last Jane heard about the modernization project until Chad sent out a memo announcing the new Dev Cloud Machine. Now, his memo explained, pretty much all cloud provider options require us to put our software into their infrastructure, which we dont want to do. Instead, weve built our own private cloud.

This so-called private cloud was an old desktop machine that was pressed into service as a WebLogic server. Gone was the painful struggle that was their edit-compile-debug cycle, and in its place was a cloud process. Jane edited the code locally, didnt run it locally, and instead checked it into CVS. An automated job (running once every fifteen minutes) pulled the code from CVS, built it, and deployed the resulting WARs onto the Dev Cloud Machine. Now Jane could connect to the WebLogic server and check her work.

The Dev Cloud Server also used the QA database as its backend, an environment which QA, shockingly, used for their own tests. This frequently caused schema mismatches and added to the overall churn.

Even if she wanted to, Jane wasnt allowed to go back to the old process- since the developers no longer needed WebLogic, corporate policy was that it was now forbidden. This rule was enforced by a script that deleted WebLogic installs with every bootup. For consistency, Chad explained, we want all of the developers to use the same process, and that process is the Dev Cloud Machine.

Some time after this policy change, Janes SameTime client stopped working. Maybe the WebLogic policy broke a DLL somewhere, maybe a file or the registry got corrupted somehow. Jane had no power to reinstall, so she raised a ticket. It vanished into wherever tickets go to get ignored by the Help Desk, and Jane did her best to focus on getting work done.

Every few days, Jane would repeat the same conversation with Chad. Hed call her into his office, and say, We have a problem with your SameTime logins…

Yes, Jane said. Ive raised a ticket. I can try and get it escalated.

After a few rounds of this, though, the conversation changed.

I have tried to stress the importance of our company policies, Chad said, specifically regarding SameTime. And I have to say, your lack of compliance on this front has become a serious problem. Were going to have to ask you to clean out your desk…

Jane didnt bother to mount a defense, and walked out happier than shed been since she started.

[Advertisement] Use NuGet or npm? Check out ProGet, the easy-to-use package repository that lets you host and manage your own personal or enterprise-wide NuGet feeds and npm repositories. It's got an impressively-featured free edition, too!

http://thedailywtf.com/articles/the-productivity-leader


Метки:  

CodeSOD: OutputCache All The Things

Понедельник, 25 Января 2016 г. 14:30 + в цитатник

Treasure chest color

Steam. AT&T. Marks and Spencer. Bebo. What do they all have in common? One morning, as customer support tickets rolled in at her online retail firm, it became Belle's job to find out.

Belle had inherited the codebase, which had originally been made overseas in India. It seemed as solid as any offshored website could be—which is to say, it had a million different quirks and the source code made her want to vomit, but it had been tested until the BA got tired of filing bugs and just decided to put it in prod.

So Belle expected it to get basic functionality like ordering a product right. Alas, that assumption was unfounded. While the BA's testing had been, for all intents and purposes, single-threaded, no sooner had the doors been opened to the public than reports came in of users being greeted by the wrong name, and with the wrong list of stored credit cards. Once the Ops guys rolled it back, Belle girded her loins and dove into the code head-first.

The first thing she found while tracing the retrieval of user credentials was this gem:


public static UserInfo GetUser()
 {
 UserInfo user = null;

 if (HttpContext.Current.Session == null)
 user = (UserInfo)Thread.GetData(Thread.GetNamedDataSlot("USER"));
 else
 {
 try
 {
 user = (UserInfo)HttpContext.Current.Session["USER"];
 }
 catch (Exception ex)
 {
 
 }
 }
 
 return user;
 }
 
 

Nobody was quite sure why it used thread-local storage. At first glance, it just seemed like a belt-and-suspenders approach. After all, HttpContext.Current did something very similar conceptually, but bounded to a single request instead of a thread.

And therein lay the problem. ASP.NET used a thread pool, meaning data stored for one user in the thread-local storage would be reused for the next session-less user.

Compounding the issue was the following snippet:


 [OutputCache(Duration = 1)]
 public class ControllerBase : Controller
 {
 //Boring stuff here
 }
 
 

This would normally be fine, if a little strange; the cache duration being 1 second would raise some eyebrows, but there were worse caching strategies. However, because the user information was fetched from thread-local storage instead of being part of the controller's responsibility, there was nothing to break the cache for different users. They all seemed identical to the controller. So after User 1's thread was reused by User 2, everyone who hit the site within one second of User 2 also saw User 1's data, session or no session.

There's a reason cache invalidation is one of the Two Hard Things in Computer Science.

Fixing the cache timeouts was easy, but corporate policies got in the way of changing the bizarre session problems. That was "logic," and changing programming logic belonged to the team that wrote the code: offshore. Belle escalated up to management with an explanation of the thread-local problem. Management escalated to offshore, they debated whether this was rework or a bug (for the purposes of deciding who would pay for it), and eventually, someone fixed it ... by making sure to spin up a new thread before calling GetUser.

[Advertisement] Release! is a light card game about software and the people who make it. Play with 2-5 people, or up to 10 with two copies - only $9.95 shipped!

http://thedailywtf.com/articles/outputcache-all-the-things


Метки:  

Error'd: There's Nothing to See Here

Пятница, 22 Января 2016 г. 14:00 + в цитатник

"Really. There's nothing to see here. Move along," wrote John A.

"You know, seeing this kind of puts every update into question," writes Alex K.

Mark W. wrote, "When I first connected to Dell Support, I was told I was number 192(!) in the queue. Two hours later, I finally connected with Gopalam, only to get this response.?"

"Maybe I should try again later? Or perhaps contact the site administrator if the problem persists?" writes Alex K.

Luc F. wrote, "That one time I want to work, a couple of zombies is stopping me."

"I'm not so sure if my baby will like this new 'F...ckwheat' flavor," writes Pawel D.

Michael W. wrote, "You'd think, of all companies, that Ikea would do Unicode correctly."

[Advertisement] Release! is a light card game about software and the people who make it. Play with 2-5 people, or up to 10 with two copies - only $9.95 shipped!

http://thedailywtf.com/articles/there-s-nothing-to-see-here


Метки:  

CodeSOD: The Helpful Customer

Четверг, 21 Января 2016 г. 14:30 + в цитатник

Sven built a PHP-based website on contract then handed it off to his customer, Bob.

You wont be getting a lot of support calls from me, Bob said, because I actually know a thing or two about PHP. Ill be maintaining this myself.

Sven smiled, nodded, and moved on to the next contract. Months later, Bob sent him an email. Hey, sometimes, the submit button isnt available, and Id like the submit button to appear all the time, but I cant figure it out.

Sven was busy, didnt reply right away, and wasnt terribly surprised when his customer pinged him back: Nevermind, I got it.

Eventually, though, Bob did find a problem he wasnt confident enough to solve himself. When Sven had handed it off, the logic to show the submit button looked like this:


        

Bobs revisions to make it so that the submit button always appeared?


        


        
[Advertisement] Use NuGet or npm? Check out ProGet, the easy-to-use package repository that lets you host and manage your own personal or enterprise-wide NuGet feeds and npm repositories. It's got an impressively-featured free edition, too!

http://thedailywtf.com/articles/the-helpful-customer


Метки:  

Foxxy Professionalism

Среда, 20 Января 2016 г. 14:30 + в цитатник

It was the mid-nineties and the Iron Curtain in urban Kerblekistan had come crashing down. Everything was in turmoil, and people were trying to make up for all of the years lost behind the locked borders by trying everything with enthusiasm. The WWW was still in its infancy, but that didn't stop the budding entrepreneurs.

The cover of the FoxPro developer's guide.

Enter a young whippersnapper, still in high school. Daddy hooked him up with a buddy of his at a certain state institution. Now don't go imagining secret agencies or ministries-of-defense; we're talking more like parks-and-recreation. Therein was a department that still had a nice chunk of unspent budget. In the sweet tradition of bureaucrats everywhere, they were looking to spend it and hopefully wind up with something to show for it.

The kid went to meet the head of the department. He took the bus to a narrow street near the center of the city. The building guards checked him out and let him in. The interior was the expected pre-iron-curtain Kerbleki decor; the ancient elevator, the carpeted dark corridors, the musty offices and portraits of stoic leaders overseeing all.

The department head was a nice enough older gentleman. He explained "Look kid, we have to manage a lot of people and resources. We keep it all in these notebooks and ledgers, with hand and pen." He opened up the big iron closet and the kid saw row upon row of paper files. He continued: "We got this spare PC around. Do you think you can do something to put it all in there?"

The young boy was sure he could, so the head promised a nice chunk of change for the work.

The kid hooked up the 286-PC running MS-DOS and decided to go with Fox Pro. He drew up some menus and UIs. He planned some database files. He spent his summer vacation entering all the data from the files into the computer. He ironed out the bugs and made it work.

And work it did. It had search. It had all kinds of nifty tools for stuff they used to have to do by hand. It printed reports to the printer. It did backups on floppy disk. For its day, it was pretty slick.

Everyone was ecstatic and the kid got his money. The department showed off the program to everybody.

Sure, they still had to keep manually entering the data into paper files (that was the official way after all). But once they also entered it into the PC they could do all kinds of neat stuff with it, in mere seconds.

Apparently, Kerblekistan hadn't yet learned how real IT projects turn out...

A couple of years later, the kid was now a young man at college. One day Daddy called again, to arrange a meeting with the old department head. He said that there was some more money to be made. In dire need of cash, the kid took a break from girls, booze and pool halls and went back to work.

The scenery had changed. The old institution was no longer drab and under the watchful eyes of Kerbleki leaders. It had been westernised and was much nicer.

The department head was happy to see the kid. They still used his program every day. The old PC was, amazingly, still running perfectly, in its corner, if under several sedimentary layers of dust.

The department head mentioned that they now all had these nicer, faster PC's. They needed to be able to use the program from each of their own PCs, and perhaps add some stuff, like getting reports out as PDF, and sending them over email. He then offered a bit of cash up front, and there would be some nice money in it for success.

Now, you're probably smirking and settling down in your armchair to better enjoy this part. You're saying to yourself, I smell a classical Fox Pro "multi-client" monstrosity, built with single-lock files in Novell network shares.

But you're not giving the young guy enough credit. Between all the girls and boozing the guy managed to do some reading. He looked over the PC's and the head guys' box was the best and by far the most powerful. He told the boss "We're going need one PC to be the 'master'; it will have to be on for the others to work." Since the boss was the first one into the office in the morning anyway, he agreed.

So the young guy got to work. They had Windows 98 on the PC. He slapped installations of Apache and MySQL on there (because adding web servers and the internet always speeds things up). He started designing web pages and relational databases. He wrote some scripts to port data from the Fox Pro files over to MySQL. Sadly, he couldn't find the original sources for the program anywhere, but it would be OK; it's not like Fox Pro translates well to PHP anyway. Besides, the old guy probably knew the procedures by heart.

So one day it was finally done, sort of. He felt that it wasn't exactly his best work ever. Any search at all took ages. Maybe he hadn't quite grasped those "index" things yet. He poked at it for a few more days but time was running short.

He didn't know if the problem was his inability to make things efficient in MySQL, that the web-stuff was more expensive (chronologically) than he thought, both, or something else. After all, PHP had been around for a few years, so it must be stable and fast, right? Maybe MySQL was too new and there were unknown issues? What performance problem could possibly be caused by web servers?

Finally, he got into a bit of a panic. This stuff was cutting into his chicks and booze time and it wasn't getting any better. He went in one morning, slapped it on the boss's PC, showed him around and then excused himself for a rapid exit. He disappeared, didn't return the advance money and left daddy to deal with his old buddy.

So they wound up still using the original system on the 286 until the old guy retired a couple of years later. And you'll be happy to know that they managed to spend the budget that year anyway.

By a show of hands, who thinks the kid would go on to have a bright future in software management?

[Advertisement] Release! is a light card game about software and the people who make it. Play with 2-5 people, or up to 10 with two copies - only $9.95 shipped!

http://thedailywtf.com/articles/foxxy-professionalism


Метки:  

CodeSOD: Reloaded Commands

Вторник, 19 Января 2016 г. 14:30 + в цитатник

William Heimbinger joins the ranks of developers who come to us to confess their sins. This particular sin was committed when he was but a young child of fifteen years old, which raises more questions than it answers.

Young William was writing Perl and building an anti-spam bot for IRC channels. As he wrote code, he wanted to quickly reload the module to test it, but actually learning how to reload modules looked like too much work. William decided to reinvent that wheel, using a hammer he already knew.

With a trivial block of Perl code:

foreach my $command ( @{$::commands->{command}} ) {
  if ($cmd=~/$command->{cmd}/) {
    eval $command->{content}; warn $@ if $@;
  }
}

William could reload all of the commands his bot needed to handle. And what, exactly, was he loading them from? Why, an XML file, of course.


  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  

This combination of XML and Perl may have had some serious side effects on Williams mental health, or perhaps theyre just a sign of a disturbed mind. Either way, this design has been removed from the current version of his bot.

[Advertisement] Use NuGet or npm? Check out ProGet, the easy-to-use package repository that lets you host and manage your own personal or enterprise-wide NuGet feeds and npm repositories. It's got an impressively-featured free edition, too!

http://thedailywtf.com/articles/reloaded-commands


Метки:  

The Backup Pipeline

Понедельник, 18 Января 2016 г. 14:30 + в цитатник
Dick was the main man in charge of his homegrown facilities-management system known as Q-Max. His brainchild was utilized across a large office complex to enter and track building maintenance tasks. Whenever a sink was broken, toilet clogged, or a foul-smelling science experiment had to be exterminated from a fridge, Q-Max was there to track and route the incident.

While that was its original intent, Dick wound up selling the office managers on expanding its role to include reporting that would help them make budgetary decisions. It helped them determine which maintenance guys deserved a raise and which buildings needed renovations the most. So despite the maintenance department despising Q-Max because it made them do stuff, management loved every bit of it. Little did they know how precarious the system was on the backend.

Travan™TR-3 Magnetic Tape Cartridge (8744993952) Dick focused on keeping this amazing application running, and let the company's "Disaster Recovery Team"- one guy named Pete- worry about the worst case scenarios. They kept a regular offsite backup of its data so that in case of something catastrophic like a meteor strike, Q-Max would not go the way of the dinosaurs. Their backup system was quite simple, yet had a necessary workaround step - Every night around midnight an Oracle backup was created on the database server. From there, they copied to an offsite tape backup. Due to infrastructure limitations- bandwidth and reliability, mostly- this mirroring process had to run to get the backup to a location the tape robot could get its iron clutches on.

Eventually Dick and Q-Max grew even bigger and got a larger budget to spend on infrastructure. Some network upgrades allowed Pete to have a backup system which could copy a backup directly to the tape library, thus eliminating the need for that silly mirroring job. The new system was implemented and taking nightly backups was a breeze.

A few years passed as Q-Max continued to have its automated backups taken every single night. One cold winter's eve, an old pipe that happened to run over the office's server room froze and burst. One of the many casualties of the unplanned cold shower was the database server that housed Q-Max. Pete called Dick frantically one night while he was home sipping hot cocoa.

"DICK, I NEED YOUR HELP! There's water everywhere!" Pete shouted to him. "It's raining in the server room!"

Thinking Pete was delusional, Dick calmed him down to get the full story. The loss of the database server and several others was troubling, but at least they still had their trusty offsite backup tapes! "Man, that sucks. I'll come in to help clean up and salvage what we can. In the meantime, put in an urgent request to have the last backup tape delivered first thing in the morning!"

Since Q-Max was down and there were no maintenance people to be found, Dick and Pete spent the night with mops and buckets cleaning up the pipe's mess. Around 7 AM, Dick was paged down to the lobby for a delivery. "The tape is here!" he exclaimed with joy, eager to get Q-Max back online.

Dick brought the tape back to the now-dry server room and prepared to restore from it on an alternate database server. The tape directory stared back at him blank. "That's odd, there's nothing in here. They must have sent the wrong tape!" Dick put in an angry call to the company that housed their tapes. They checked other tapes that had been used for Q-Max backups only to find all of them were blank.

Furious, Dick could think about nothing but lawsuits against the company that screwed up their entire backup system. In the meantime, he dispatched Pete to prove the backup job on their side was working. Pete ducked out for an hour or so. When he returned, he looked like he'd just been diagnosed with some horrible disease.

"I checked out the backup job and, well, you're not going to like this..." Pete muttered nervously.

"Ok... what exactly happened?" Dick asked, unsure if he actually wanted the answer.

"Well, the good news is our backup job is working fine. However... Do you remember long ago when we had that stupid mirror job to copy the local backup to the external tape drive? I kinda, sorta, forgot to disable that. So after our new backup job runs, the old one copies an empty directory over top of it, and the legitimate backup is lost. It's been like that. For years."

If there was any remaining water from the pipe bursting, it would have turned to steam as Dick became red hot with anger towards Pete. Dick would have to strangle him later, though. First he had to figure out how to rebuild Q-Max's data from the ground up.

[Advertisement] BuildMaster is more than just an automation tool: it brings together the people, process, and practices that allow teams to deliver software rapidly, reliably, and responsibly. And it's incredibly easy to get started; download now and use the built-in tutorials and wizards to get your builds and/or deploys automated!

http://thedailywtf.com/articles/the-backup-pipeline


Метки:  

Error'd: Blame the Computer

Пятница, 15 Января 2016 г. 14:00 + в цитатник

Jason M. wrote, "A city park has a computer problem so unsolvable, that they made a sign about it."

"So, does this mean that they owe me 14 photos?" writes Zahid H.

Mark W. wrote, "Sure, let's blame the kernel for why the bus is late. Why not?"

"After uninstalling Visual Studio Enterprise, I was surprised to learn that a reboot could bring it back," writes Daniel W.

"This stylus has some sweet features," wrote Joe L.

"I'm not so sure if my baby will like this new 'F...ckwheat' flavor," writes Toby J..

Dan M. wrote, "Went looking for credit card info, and had a flashback to the torment of high school Latin."

"The company I work for is a food distributor, and I manage our website," Russ writes, "Apparently, we now offer 'delete meat'."

[Advertisement] Scout is the best way to monitor your critical server infrastructure. With over 90 open source plugins, robust alerting, beautiful dashboards and a 5 minute install - Scout saves youvaluable engineering time. Try the server monitoring you'll M today.Your first 30 days are free on us. Learn more at Scout.

http://thedailywtf.com/articles/blame-the-computer


Метки:  

CodeSOD: The Flasher

Четверг, 14 Января 2016 г. 14:30 + в цитатник

Michael H sends us some code that probably deserves a NSFW warning for exhibitionism. This code is a confusing bit of metaprogramming that… well, shouldnt be allowed near schools or playgrounds.

function load_class_public($class) {
        static $classes;
        if (! $classes)
                $classes = array();
        $classname = $class . '_Publicified';
        if ($classes[$classname])
                return $classname;
        $codez = file_get_contents(PATH . '/classes/class.' . $class . '.php');
        $codez = preg_replace('/\bprivate\b/', 'public', $codez);
        $codez = preg_replace('/\bprotected\b/', 'public', $codez);
        $codez = preg_replace('/\bclass\s+' . $class . '\b/', 'class ' . $class . '_Publicified', $codez);
        $codez = preg_replace('/\<\?php/', '', $codez);
        eval($codez);
        $classes[$classname] = $classname;
        return $classname;
}

So, lets start with the variable name $codez. Once we finish rolling our eyes, we can move onto the real horror: it loads a PHP file based on the class name, it uses regexes to convert every use of the keywords private or protected into public, changes the classname Foo to Foo_Publicified, and then evaluates the resulting code to create a new classname.

And then it returns that classname for instantiation elsewhere in the code. This is the work of someone dangerously clever, but not terribly bright. Michael isnt sure why its there, or what purpose it serves, but it is being called.

[Advertisement] Use NuGet or npm? Check out ProGet, the easy-to-use package repository that lets you host and manage your own personal or enterprise-wide NuGet feeds and npm repositories. It's got an impressively-featured free edition, too!

http://thedailywtf.com/articles/the-flasher


Метки:  

The Carte Blanche Pattern

Среда, 13 Января 2016 г. 14:30 + в цитатник

"Rejoice! Rejoice! Emmanuel shall come to thee, O' Israel!"

Something was definitely up. Ricardo, the team lead, hadn't stopped singing carols that day. Sure, it was a few weeks before Christmas, but that was hardly an excuse to serenade the whole office. No, something had happened, and Erika was determined to keep out of it.

This wasn't the first time Ricardo had gotten prematurely excited over something. Usually dour and unhappy, when he truly believed in a project, he'd hype himself up about it until there was no talking sense into him. It was best to lie low. If you got sucked in, you'd only be blamed when the inevitable fallout crushed his spirit yet again.

Unfortunately, fate seemed to have it in for Erika. Ricardo made a beeline for her cube, still singing carols.

"I bring ye tidings of great joy!" he announced, knocking on the sidewall of her cube. "They agreed to rewrite the frontend—this time, with a CMS!"

That was good news. Nobody liked the aging frontend, but nobody ever seriously broached the subject of redoing it, not with the usual budget austerity. It worked, and it was "only" six years old, they should be able to patch anything that had security implications and keep it running for another ten years. Just like a used car, right?

The biggest complaint was that it had no Content Management System. Every tiny image tweak Marketing wanted, every news article, every dynamic piece of content was achieved via a promotion. They'd separated content from structure as best they could in small payments on the tech debt over the years, but the prospect of a proper CMS, where they could hand the keys to Marketing and wash their hands of the content, was like Christmas come early. Still, Erika couldn't help but wonder where the catch was.

"What's the deadline?" she asked, already preparing to cringe.

"That's the best part: you won't have to worry about the project or the tech design or anything," Ricardo answered. "They're sending over a couple of guys from the East Branch to run the whole thing. Apparently they've had a CMS for a year now and love it, so they want to build the exact same thing here."

Erika bristled. If they had a CMS in the East Branch, why did they give her so much crap about putting one in Corporate HQ? And now a couple of clowns were coming in to tell the team how to do their jobs?

Sensing her frustration, Ricardo beamed at her. "Hey, don't worry. I know these guys. They're a couple of certified geniuses. I hear they used to work at Google! They know what they're doing, they just need us to supply a few extra pairs of hands and they'll run the whole show. I got Marketing to agree to give them free run of it, carte blanche, whatever they say goes. This is going to be the best project we've ever done!"

A year later, it was almost Christmas yet again—but this time, there were no festivities in the air. Erika's hair had grown out and reverted to its natural colour; she couldn't be bothered to head to the salon, not when every day she felt like drinking herself into a stupor. Marketing seemed bound and determined to take all of IT down and replace them with offshore developers, and with good reason: every test they ran on the shiny new frontend found some new "Critical" bug. Validation was never quite right. The workflow was nothing like the design had promised. The styles were off. The images were wrong. The CMS was serving up content scheduled for the future, but only on Tuesdays. Every bug that got fixed introduced another four.

Ricardo spent most of his time in meetings, trying to quell the Marketing demons and lull them back into their unhappy slumber. Erika's task was testing the application as rapidly as she could, despite no real QA training. If Marketing's testers received another bad build, all hell would break loose. The last glimmer of hope within her suggested that if she could just get a look at the code, maybe she could figure out what was wrong. Maybe she could solve it. There had to be a Node module that could fix the systemic problems, right?

"Which branch is the code on?" asked Erika, passing Ricardo in the hallway. "I thought I'd take a look—"

"Don't you dare." Ricardo actually stopped to grip her shoulders tightly, a terrified look in his eyes. "I thought that last month, and I've regretted it ever since. I've seen things I can never unsee in that codebase. Single letter variable names. Views mixed with models mixed with half-hearted validation. Tabs and spaces together, Erika! As if they belonged that way! Don't you dare throw away your sanity on this project, you hear me?"

Ricardo's theatrics aside, Erika was now more convinced than ever that she had to see the code for herself. Not because she could fix it, but because she was morbidly curious. When Ricardo wasn't looking, she poked around the repo, checked out a working copy, and sneaked home with her laptop and a bottle of chardonnay to see what she could find.

The first file she opened was the account creation workflow. Remembering Ricardo's words about spacing, she ran it through Sublime's re-indention methods before she read any of it. Soon after, she swapped the chardonnay for whiskey, but she began to comprehend the problem: these guys were not developers. They didn't understand how to construct software. Whatever they'd done at the East Branch was, had to be, a fluke. Their best code was all ripped straight from StackOverflow. They were desperately trying to make intelligent decisions, but they kept coming up with bizarre conventions like this one:


function matchPasswordsFn(e) {
        if (!(e && e.type)) return;
        $(e.delegateTarget).off("blur focusout", e.handleObj.selector, matchPasswordsFn);

        var type = e.type,
            txtCnfNewPassword = "#SecurityInfo_ConfirmPassword",
            SecurityInfoConfirmPassword = "#SecurityInfo_ConfirmPassword";
             matchPasswordsFn = function (e) {
            if (!(e && e.type && type === e.type)) return;
            var password = $(e.target);
            switch (!0) {
                case password.is("#SecurityInfo_Password"):
                    if ("string" === typeof SecurityInfoConfirmPassword)
                        SecurityInfoConfirmPassword = password.parents('form').find(SecurityInfoConfirmPassword);
                    SecurityInfoConfirmPassword.prop("pattern", escapeForRegEx(password.val()));
                    break;
                case password.is("#SecurityInfo_NewPassword"):
                    if ("string" === typeof txtCnfNewPassword)
                        txtCnfNewPassword = password.parents('form').find(txtCnfNewPassword);
                    txtCnfNewPassword.prop("pattern", escapeForRegEx(password.val()));
                    break;
            }
        };
        return $(e.delegateTarget).on(type, e.handleObj.selector, matchPasswordsFn), matchPasswordsFn.call(this, e)
    };
    function escapeForRegEx(text){
        return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");

In order to validate that passwords matched, they constructed a regex pattern consisting of the first password, and validated the confirmation password against it. They hand-rolled their own escape library, using (of course) a regex to do the escape.

"When all you have is a regex hammer ..." mused Erika, pouring herself another whiskey sour.

The project limped along, much more successful once Erika stopped testing and started fixing. The number of bugs slowly reduced. While the project was still a turd, at least it was a turd with a CMS, which was better than they'd been working with before. The launch party was mellow and subdued, mostly sporting an air of relief that the darn thing got into production at all.

And the East Branch pair were fired two weeks after returning to their branch. Not because of the new frontend; somehow, that was Ricardo's fault. No, it was because in their absence, the East Branch CMS had broken severely, and people had realized it was a poorly written, buggy turd as well.

[Advertisement] Release! is a light card game about software and the people who make it. Play with 2-5 people, or up to 10 with two copies - only $9.95 shipped!

http://thedailywtf.com/articles/the-carte-blanche-pattern


Метки:  

CodeSOD: Ch-ch-ch-changes

Вторник, 12 Января 2016 г. 14:30 + в цитатник

Archie poked around in his companys billing system. This was a mistake, because that system is implemented largely in PL/SQL, and only a developer made from the sternest stuff can deal with PL/SQL.

Like most PL/SQL applications, the Oracle database is the closest thing they have to version control. Each developer makes changes in the live dev environment and then hopes for the best. They dont use TOAD or SQLPlus or any normal tool for making these changes- they have to use an in-house developed GUI, because that GUI tracks their changes and writes rows into a database called VersionDB. When they finish a patch and want to release the changes to their customer sites, they send a copy of the VersionDB and let a simple script apply all of those changes.

It works about as well as youd expect.

Now, its important to note that Oracle defaults to using ANSI NULLs, which means

NULL != NULL
. I note this, because it means if you have an old version of a row, and a new version of a row, you cant simply determine if theyre different by using code in the form:
IF oldValue != newValue THEN
  /* do some stuff */
END IF;

If both oldValue and newValue are NULL, this code will mistakenly think that theyve been changed. The obvious solution then, is to throw some NULL guards:

IF NOT oldValue IS NULL AND oldValue != newValue THEN
  /* do some stuff */
END IF;

The problem with this is that the intent of the code is no longer clear. So our next instinct is to build some sort of function to handle this. Thats not a bad instinct, but it can lead to some very bad results…

--**********************
-- Changed() - Public
--  Indicates if the value has been changed.
--
  procedure Changed (
    a_OldValue      varchar2,
    a_NewValue      varchar2,
    a_Changed     in out boolean
  ) is
  begin
    a_Changed := a_OldValue is null and a_NewValue is not null or
                 a_NewValue is null and a_OldValue is not null or
                 a_OldValue != a_NewValue;
  end Changed;
--
--**********************
-- Changed() - Public
--  Indicates if the value has been changed.
--
  procedure Changed (
    a_OldValue      number,
    a_NewValue      number,
    a_Changed     in out boolean
  ) is
  begin
    a_Changed := a_OldValue is null and a_NewValue is not null or
                 a_NewValue is null and a_OldValue is not null or
                 a_OldValue != a_NewValue;
  end Changed;
--
--**********************
-- Changed() - Public
--  Indicates if the value has been changed.
--
  procedure Changed (
    a_OldValue      date,
    a_NewValue      date,
    a_Changed     in out boolean
  ) is
  begin
    a_Changed := a_OldValue is null and a_NewValue is not null or
                 a_NewValue is null and a_OldValue is not null or
                 a_OldValue != a_NewValue;
  end Changed;
--
--**********************
-- Changed() - Public
--  Indicates if the value has been changed.
--
  procedure Changed (
    a_OldValue      timestamp with time zone,
    a_NewValue      timestamp with time zone,
    a_Changed     in out boolean
  ) is
  begin
    a_Changed := a_OldValue is null and a_NewValue is not null or
                 a_NewValue is null and a_OldValue is not null or
                 a_OldValue != a_NewValue;
  end Changed;
--
--**********************
-- Changed() - Public
--  Indicates if the value has been changed.
--
  function Changed (
    a_OldValue      varchar2,
    a_NewValue      varchar2
  ) return boolean is
    t_Changed boolean;
  begin
    Changed(a_OldValue, a_NewValue, t_Changed);
    --
    return t_Changed;
  end Changed;
--
--**********************
-- Changed() - Public
--  Indicates if the value has been changed.
--
  function Changed (
    a_OldValue      number,
    a_NewValue      number
  ) return boolean is
    t_Changed boolean;
  begin
    Changed(a_OldValue, a_NewValue, t_Changed);
    --
    return t_Changed;
  end Changed;
--
--**********************
-- Changed() - Public
--  Indicates if the value has been changed.
--
  function Changed (
    a_OldValue      date,
    a_NewValue      date
  ) return boolean is
    t_Changed boolean;
  begin
    Changed(a_OldValue, a_NewValue, t_Changed);
    --
    return t_Changed;
  end Changed;
--
--**********************
-- Changed() - Public
--  Indicates if the value has been changed.
--
  function Changed (
    a_OldValue                            timestamp with time zone,
    a_NewValue                            timestamp with time zone
  ) return boolean is
    t_Changed boolean;
  begin
    Changed(a_OldValue, a_NewValue, t_Changed);
    --
    return t_Changed;
  end Changed;

I particularly like the utility of having both PROCEDURE versions with output parameters and FUNCTION versions that wrap them. The real kicker is that, with all of that code, the Changed functions are only called about a dozen times in the program.

[Advertisement] Use NuGet or npm? Check out ProGet, the easy-to-use package repository that lets you host and manage your own personal or enterprise-wide NuGet feeds and npm repositories. It's got an impressively-featured free edition, too!

http://thedailywtf.com/articles/ch-ch-ch-changes


Метки:  

Management Reality

Понедельник, 11 Января 2016 г. 14:30 + в цитатник

Merriam-Webster says that synonyms of stupidity include boneheadedness, brainlessness, denseness, dim-wittednes, dumbness, mindlessness, senselessness, thickness, vacuity and witlessness (among others). Perhaps they should add management to the list.

A company breakroom, with vending machines

For some reason, managers tend to make leaps-of-faith in the realm of technology. If they think that they know the meanings of two words, then there must be a connection between those two words. Unfortunately, whether the connection is real or imagined, they seem to proceed as though it were always real.

A couple of years ago, Harold worked for a modest company. It was your garden variety organization with the usual amenities (a break room, candy and soda machines, etc.). In this place, strict adherence to the Dilbert Principle was the standard for hiring and promotion, and the CIO was a prime example of this rule in action. The powers-that-be believed this individual to have an in-depth understanding of how technology worked, and how different roles (e.g.: developer, QA, etc.) interacted, and so he was promoted to Chief Insipient Oaf.

The CIO had a very high opinion of himself and of his supreme knowledge and mastery of all things. After reading an article on the subject on the InterWebs, the CIO decreed that a new high-tech think-tank would be created to foster design, productivity and camaraderie within the organization.

This facility would have a certain Feng Shui to drive the layout and ambience. It would have a specific quantity of each of a certain type of computer. There would be erasable surfaces upon which new brillance could be scribbled. It would showcase successful projects, as well as industry awards. It would even have a high-tech table capable of dynamically expanding to match the number of folks in the room (e.g.: a dining table with additional leaves).

Teams would be able to brainstorm new solutions in record time in this conducive environment. Inter-team sessions would enable people to optimize work flow and productivity across departments. This new think-tank would elevate their performance to levels worthy of the word enterprise.

He even wrote about it in non-peer-reviewed magazines, without discussing it with anyone above - or below him in the organization.

One day, the CIO's minions were sitting around their department break room, reading and discussing their leaders' bragging about their new think-tank. In particular, since they'd never been told of its existence, they were trying to figure out where it was located. After all, they had no room that featured such computers, awards or successful projects, and it might be nice to leverage such a room for its intended purpose.

Fortunately, the CIO had mentioned enough facts in the article about the think-tank that the staff was finally able to deduce that he was actually talking about their break room.

One can only wonder what might have happened if someone had actually requested a brainstorming session in the think-tank...

[Advertisement] BuildMaster is more than just an automation tool: it brings together the people, process, and practices that allow teams to deliver software rapidly, reliably, and responsibly. And it's incredibly easy to get started; download now and use the built-in tutorials and wizards to get your builds and/or deploys automated!

http://thedailywtf.com/articles/management-reality


Метки:  

Error'd: Let's Party like it's 2005

Пятница, 08 Января 2016 г. 14:00 + в цитатник

"I can't tell if it's a proofreading or a 'Y2k15' glitch," Ken L. writes.

Maciek O. wrote, "Feedback? Well, it's broken, for starters."

Nick W. writes, "Call me old fashioned, but those baby names seem a little too mainstream for me."

"Arby's is supposed to 'have the meats', but today it looks like they can't even have the menu," wrote Jeff T.

Chris wrote, "I would totally give up on the M&M's to take home a 'concat' for $3.00."

"Today is Friday, November 27th," David writes, "or is it?"

Michael wrote, "It seems that even the devs think that successful completion is exceptional!"

"Nice try - not going to double click, even if the world might depend on it," writes Scott.

[Advertisement] Manage IT infrastructure as code across all environments with Puppet. Puppet Enterprise now offers more control and insight, with role-based access control, activity logging and all-new Puppet Apps. Start your free trial today!

http://thedailywtf.com/articles/let-s-party-like-it-s-2005


Метки:  

CodeSOD: Good Idea, Bad Idea

Четверг, 07 Января 2016 г. 14:30 + в цитатник

After years of neglecting their command line tools, Microsoft decided to try and build a grown-up set of administrative tools, and released PowerShell. Nearly a decade later, and many of their flagship services still dont integrate neatly with PowerShell. Good Idea, Bad Idea The syntax is a bit messy, and the promises of an object-oriented shell never quite came to fruition. PowerShell is a great idea, executed poorly. For all that, it still offers certain advantages compared to the Unix family of shells, and is certainly worlds better than ol CMD.EXE.

Speaking of good ideas executed poorly: backups arent a good idea, theyre a great idea. And when Tommy took over as an Active Directory engineer, he was happy to hear that his predecessor had left behind a script that backed up all their user data on a daily basis. Tommy was significantly less happy when he saw the script.

Import-Module ActiveDirectory
$Date1 = get-date -uformat "%m-%d-%Y"
$LogFile = "D:\Reports\UserInfoDetailed.$Date1.csv"
echo "AccountExpirationDate*accountExpires*AccountLockoutTime*AccountNotDelegated*AllowReversiblePasswordEncryption*BadLogonCount*badPasswordTime*badPwdCount*C*CannotChangePassword*CanonicalName*City*CN*codePage*Comment*Company*Country*countryCode*Created*createTimeStamp*Deleted*Department*Description*DisplayName*DistinguishedName*Division*DoesNotRequirePreAuth*dSCorePropagationData*EmailAddress*EmployeeID*EmployeeNumber*employeeType*Enabled*$extensionAttribute10*$extensionAttribute13*Fax*GivenName*HomeDirectory*HomedirRequired*HomeDrive*HomePage*HomePhone*Initials*instanceType*isCriticalSystemObject*isDeleted*LastBadPasswordAttempt*LastKnownParent*LastLogonDate*LockedOut*lockoutTime*LogonWorkstations*Manager*MemberOf*MNSLogonAccount*MobilePhone*Modified*modifyTimeStamp*Name*nTSecurityDescriptor*ObjectCategory*ObjectClass*ObjectGUID*objectSid*Office*OfficePhone*Organization*OtherName*PasswordExpired*PasswordLastSet*PasswordNeverExpires*PasswordNotRequired*POBox*PostalCode*PrimaryGroup*primaryGroupID*ProfilePath*ProtectedFromAccidentalDeletion*pwdLastSet*SamAccountName*sAMAccountType*ScriptPath*sDRightsEffective*ServicePrincipalNames*SID*SIDHistory*SmartcardLogonRequired*State*StreetAddress*Surname*Title*TrustedForDelegation*TrustedToAuthForDelegation*UseDESKeyOnly*userAccountControl*UserPrincipalName*uSNChanged*uSNCreated*whenChanged*whenCreated" > $Logfile
# get-adUser -filter * -Property * | select * -Exclude userCertificate, showInAddressBook, Certificates | Export-csv $LogFile -NoTypeInformation
get-adUser -filter * -Property SamAccountName | Select SamAccountName | Foreach {$_.SamAccountName} > Accounts.txt
        $Accounts = get-content Accounts.txt
        Foreach ($Account in $Accounts)
                {$AccountExpirationDate = get-adUser $Account -Properties AccountExpirationDate | select AccountExpirationDate | Foreach {$_.AccountExpirationDate}
                $accountExpires = get-adUser $Account -Properties accountExpires | select accountExpires | Foreach {$_.accountExpires}
                $AccountLockoutTime = get-adUser $Account -Properties AccountLockoutTime | select AccountLockoutTime | Foreach {$_.AccountLockoutTime}
                $AccountNotDelegated = get-adUser $Account -Properties AccountNotDelegated | select AccountNotDelegated | Foreach {$_.AccountNotDelegated}
                $AllowReversiblePasswordEncryption = get-adUser $Account -Properties AllowReversiblePasswordEncryption | select AllowReversiblePasswordEncryption | Foreach {$_.AllowReversiblePasswordEncryption}
                $BadLogonCount = get-adUser $Account -Properties BadLogonCount | select BadLogonCount | Foreach {$_.BadLogonCount}
                $badPasswordTime = get-adUser $Account -Properties badPasswordTime | select badPasswordTime | Foreach {$_.badPasswordTime}
                $badPwdCount = get-adUser $Account -Properties badPwdCount | select badPwdCount | Foreach {$_.badPwdCount}
                $C = get-adUser $Account -Properties C | select C | Foreach {$_.C}
                $CannotChangePassword = get-adUser $Account -Properties CannotChangePassword | select CannotChangePassword | Foreach {$_.CannotChangePassword}
                $CanonicalName = get-adUser $Account -Properties CanonicalName | select CanonicalName | Foreach {$_.CanonicalName}
                $City = get-adUser $Account -Properties City | select City | Foreach {$_.City}
                $CN = get-adUser $Account -Properties CN | select CN | Foreach {$_.CN}
                $codePage = get-adUser $Account -Properties codePage | select codePage | Foreach {$_.codePage}
                $comment = Get-ADUser $Account -Properties * | select -ExpandProperty commentForeach {$_.comment}
                $Company = get-adUser $Account -Properties Company | select Company | Foreach {$_.Company}
                $Country = get-adUser $Account -Properties Country | select Country | Foreach {$_.Country}
                $countryCode = get-adUser $Account -Properties countryCode | select countryCode | Foreach {$_.countryCode}
                $Created = get-adUser $Account -Properties Created | select Created | Foreach {$_.Created}
                $createTimeStamp = get-adUser $Account -Properties createTimeStamp | select createTimeStamp | Foreach {$_.createTimeStamp}
                $Deleted = get-adUser $Account -Properties Deleted | select Deleted | Foreach {$_.Deleted}
                $Department = get-adUser $Account -Properties Department | select Department | Foreach {$_.Department}
                $Description = get-adUser $Account -Properties Description | select Description | Foreach {$_.Description}
                $DisplayName = get-adUser $Account -Properties DisplayName | select DisplayName | Foreach {$_.DisplayName}
                $DistinguishedName = get-adUser $Account -Properties DistinguishedName | select DistinguishedName | Foreach {$_.DistinguishedName}
                $Division = get-adUser $Account -Properties Division | select Division | Foreach {$_.Division}
                $DoesNotRequirePreAuth = get-adUser $Account -Properties DoesNotRequirePreAuth | select DoesNotRequirePreAuth | Foreach {$_.DoesNotRequirePreAuth}
                $dSCorePropagationData = get-adUser $Account -Properties dSCorePropagationData | select -ExpandProperty dSCorePropagationData
                $EmailAddress = get-adUser $Account -Properties EmailAddress | select EmailAddress | Foreach {$_.EmailAddress}
                $EmployeeID = get-adUser $Account -Properties EmployeeID | select EmployeeID | Foreach {$_.EmployeeID}
                $EmployeeNumber = get-adUser $Account -Properties EmployeeNumber | select EmployeeNumber | Foreach {$_.EmployeeNumber}
                $employeeType = get-adUser $Account -Properties employeeType | select employeeType | Foreach {$_.employeeType}
                $Enabled = get-adUser $Account -Properties Enabled | select Enabled | Foreach {$_.Enabled}
                $extensionAttribute10 = get-adUser $Account -Properties extensionAttribute10 | select extensionAttribute10 | Foreach {$_.extensionAttribute10}
                $extensionAttribute13 = get-adUser $Account -Properties extensionAttribute13 | select extensionAttribute13 | Foreach {$_.extensionAttribute13}
                $Fax = get-adUser $Account -Properties Fax | select Fax | Foreach {$_.Fax}
                $GivenName = get-adUser $Account -Properties GivenName | select GivenName | Foreach {$_.GivenName}
                $HomeDirectory = get-adUser $Account -Properties HomeDirectory | select HomeDirectory | Foreach {$_.HomeDirectory}
                $HomedirRequired = get-adUser $Account -Properties HomedirRequired | select HomedirRequired | Foreach {$_.HomedirRequired}
                $HomeDrive = get-adUser $Account -Properties HomeDrive | select HomeDrive | Foreach {$_.HomeDrive}
                $HomePage = get-adUser $Account -Properties HomePage | select HomePage | Foreach {$_.HomePage}
                $HomePhone = get-adUser $Account -Properties HomePhone | select HomePhone | Foreach {$_.HomePhone}
                $Initials = get-adUser $Account -Properties Initials | select Initials | Foreach {$_.Initials}
                $instanceType = get-adUser $Account -Properties instanceType | select instanceType | Foreach {$_.instanceType}
                $isCriticalSystemObject = get-adUser $Account -Properties isCriticalSystemObject | select isCriticalSystemObject | Foreach {$_.isCriticalSystemObject}
                $isDeleted = get-adUser $Account -Properties isDeleted | select isDeleted | Foreach {$_.isDeleted}
                $LastBadPasswordAttempt = get-adUser $Account -Properties LastBadPasswordAttempt | select LastBadPasswordAttempt | Foreach {$_.LastBadPasswordAttempt}
                $LastKnownParent = get-adUser $Account -Properties LastKnownParent | select LastKnownParent | Foreach {$_.LastKnownParent}
                $LastLogonDate = get-adUser $Account -Properties LastLogonDate | select LastLogonDate | Foreach {$_.LastLogonDate}
                $LockedOut = get-adUser $Account -Properties LockedOut | select LockedOut | Foreach {$_.LockedOut}
                $lockoutTime = get-adUser $Account -Properties lockoutTime | select lockoutTime | Foreach {$_.lockoutTime}
                $LogonWorkstations = get-adUser $Account -Properties LogonWorkstations | select LogonWorkstations | Foreach {$_.LogonWorkstations}
                $Manager = get-adUser $Account -Properties Manager | select Manager | Foreach {$_.Manager}
                $MemberOf = get-adUser $Account -Properties MemberOf | select -ExpandProperty MemberOf
                $MNSLogonAccount = get-adUser $Account -Properties MNSLogonAccount | select MNSLogonAccount | Foreach {$_.MNSLogonAccount}
                $MobilePhone = get-adUser $Account -Properties MobilePhone | select MobilePhone | Foreach {$_.MobilePhone}
                $Modified = get-adUser $Account -Properties Modified | select Modified | Foreach {$_.Modified}
                $modifyTimeStamp = get-adUser $Account -Properties modifyTimeStamp | select modifyTimeStamp | Foreach {$_.modifyTimeStamp}
                #$msDS-User-Account-Control-Computed = get-adUser $Account -Properties msDS-User-Account-Control-Computed | select msDS-User-Account-Control-Computed | Foreach {$_.msDS-User-Account-Control-Computed}
                $Name = get-adUser $Account -Properties Name | select Name | Foreach {$_.Name}
                $nTSecurityDescriptor = get-adUser $Account -Properties nTSecurityDescriptor | select nTSecurityDescriptor | Foreach {$_.nTSecurityDescriptor}
                $ObjectCategory = get-adUser $Account -Properties ObjectCategory | select ObjectCategory | Foreach {$_.ObjectCategory}
                $ObjectClass = get-adUser $Account -Properties ObjectClass | select ObjectClass | Foreach {$_.ObjectClass}
                $ObjectGUID = get-adUser $Account -Properties ObjectGUID | select ObjectGUID | Foreach {$_.ObjectGUID}
                $objectSid = get-adUser $Account -Properties objectSid | select objectSid | Foreach {$_.objectSid}
                $Office = get-adUser $Account -Properties Office | select Office | Foreach {$_.Office}
                $OfficePhone = get-adUser $Account -Properties OfficePhone | select OfficePhone | Foreach {$_.OfficePhone}
                $Organization = get-adUser $Account -Properties Organization | select Organization | Foreach {$_.Organization}
                $OtherName = get-adUser $Account -Properties OtherName | select OtherName | Foreach {$_.OtherName}
                $PasswordExpired = get-adUser $Account -Properties PasswordExpired | select PasswordExpired | Foreach {$_.PasswordExpired}
                $PasswordLastSet = get-adUser $Account -Properties PasswordLastSet | select PasswordLastSet | Foreach {$_.PasswordLastSet}
                $PasswordNeverExpires = get-adUser $Account -Properties PasswordNeverExpires | select PasswordNeverExpires | Foreach {$_.PasswordNeverExpires}
                $PasswordNotRequired = get-adUser $Account -Properties PasswordNotRequired | select PasswordNotRequired | Foreach {$_.PasswordNotRequired}
                $POBox = get-adUser $Account -Properties POBox | select POBox | Foreach {$_.POBox}
                $PostalCode = get-adUser $Account -Properties PostalCode | select PostalCode | Foreach {$_.PostalCode}
                $PrimaryGroup = get-adUser $Account -Properties PrimaryGroup | select PrimaryGroup | Foreach {$_.PrimaryGroup}
                $primaryGroupID = get-adUser $Account -Properties primaryGroupID | select primaryGroupID | Foreach {$_.primaryGroupID}
                $ProfilePath = get-adUser $Account -Properties ProfilePath | select ProfilePath | Foreach {$_.ProfilePath}
                $ProtectedFromAccidentalDeletion = get-adUser $Account -Properties ProtectedFromAccidentalDeletion | select ProtectedFromAccidentalDeletion | Foreach {$_.ProtectedFromAccidentalDeletion}
                $pwdLastSet = get-adUser $Account -Properties pwdLastSet | select pwdLastSet | Foreach {$_.pwdLastSet}
                $SamAccountName = get-adUser $Account -Properties SamAccountName | select SamAccountName | Foreach {$_.SamAccountName}
                $sAMAccountType = get-adUser $Account -Properties sAMAccountType | select sAMAccountType | Foreach {$_.sAMAccountType}
                $ScriptPath = get-adUser $Account -Properties ScriptPath | select ScriptPath | Foreach {$_.ScriptPath}
                $sDRightsEffective = get-adUser $Account -Properties sDRightsEffective | select sDRightsEffective | Foreach {$_.sDRightsEffective}
                $ServicePrincipalNames = get-adUser $Account -Properties ServicePrincipalNames | select -ExpandProperty ServicePrincipalNames
                $SID = get-adUser $Account -Properties SID | select SID | Foreach {$_.SID}
                $SIDHistory = get-adUser $Account -Properties SIDHistory | select -ExpandProperty SIDHistory
                $SmartcardLogonRequired = get-adUser $Account -Properties SmartcardLogonRequired | select SmartcardLogonRequired | Foreach {$_.SmartcardLogonRequired}
                $State = get-adUser $Account -Properties State | select State | Foreach {$_.State}
                $StreetAddress = get-adUser $Account -Properties StreetAddress | select StreetAddress | Foreach {$_.StreetAddress}
                $Surname = get-adUser $Account -Properties Surname | select Surname | Foreach {$_.Surname}
                $Title = get-adUser $Account -Properties Title | select Title | Foreach {$_.Title}
                $TrustedForDelegation = get-adUser $Account -Properties TrustedForDelegation | select TrustedForDelegation | Foreach {$_.TrustedForDelegation}
                $TrustedToAuthForDelegation = get-adUser $Account -Properties TrustedToAuthForDelegation | select TrustedToAuthForDelegation | Foreach {$_.TrustedToAuthForDelegation}
                $UseDESKeyOnly = get-adUser $Account -Properties UseDESKeyOnly | select UseDESKeyOnly | Foreach {$_.UseDESKeyOnly}
                $userAccountControl = get-adUser $Account -Properties userAccountControl | select userAccountControl | Foreach {$_.userAccountControl}
                $UserPrincipalName = get-adUser $Account -Properties UserPrincipalName | select UserPrincipalName | Foreach {$_.UserPrincipalName}
                $uSNChanged = get-adUser $Account -Properties uSNChanged | select uSNChanged | Foreach {$_.uSNChanged}
                $uSNCreated = get-adUser $Account -Properties uSNCreated | select uSNCreated | Foreach {$_.uSNCreated}
                $whenChanged = get-adUser $Account -Properties whenChanged | select whenChanged | Foreach {$_.whenChanged}
                $whenCreated = get-adUser $Account -Properties whenCreated | select whenCreated | Foreach {$_.whenCreated}
                #$PropertyNames = get-adUser $Account -Properties PropertyNames | select PropertyNames | Foreach {$_.PropertyNames}
                #$PropertyCount = get-adUser $Account -Properties PropertyCount | select PropertyCount | Foreach {$_.PropertyCount}
                echo "$AccountExpirationDate*$accountExpires*$AccountLockoutTime*$AccountNotDelegated*$AllowReversiblePasswordEncryption*$BadLogonCount*$badPasswordTime*$badPwdCount*$C*$CannotChangePassword*$CanonicalName*$City*$CN*$codePage*$comment*$Company*$Country*$countryCode*$Created*$createTimeStamp*$Deleted*$Department*$Description*$DisplayName*$DistinguishedName*$Division*$DoesNotRequirePreAuth*$dSCorePropagationData*$EmailAddress*$EmployeeID*$EmployeeNumber*$employeeType*$Enabled*$extensionAttribute10*$extensionAttribute13*$Fax*$GivenName*$HomeDirectory*$HomedirRequired*$HomeDrive*$HomePage*$HomePhone*$Initials*$instanceType*$isCriticalSystemObject*$isDeleted*$LastBadPasswordAttempt*$LastKnownParent*$LastLogonDate*$LockedOut*$lockoutTime*$LogonWorkstations*$Manager*$MemberOf*$MNSLogonAccount*$MobilePhone*$Modified*$modifyTimeStamp*$Name*$nTSecurityDescriptor*$ObjectCategory*$ObjectClass*$ObjectGUID*$objectSid*$Office*$OfficePhone*$Organization*$OtherName*$PasswordExpired*$PasswordLastSet*$PasswordNeverExpires*$PasswordNotRequired*$POBox*$PostalCode*$PrimaryGroup*$primaryGroupID*$ProfilePath*$ProtectedFromAccidentalDeletion*$pwdLastSet*$SamAccountName*$sAMAccountType*$ScriptPath*$sDRightsEffective*$ServicePrincipalNames*$SID*$SIDHistory*$SmartcardLogonRequired*$State*$StreetAddress*$Surname*$Title*$TrustedForDelegation*$TrustedToAuthForDelegation*$UseDESKeyOnly*$userAccountControl*$UserPrincipalName*$uSNChanged*$uSNCreated*$whenChanged*$whenCreated" >> $Logfile
                #echo "$AccountExpirationDate*$accountExpires*$AccountLockoutTime*$AccountNotDelegated*$AllowReversiblePasswordEncryption*$BadLogonCount*$badPasswordTime*$badPwdCount*$CannotChangePassword*$CanonicalName*$City*$CN*$codePage*$Company*$Country*$countryCode*$Created*$createTimeStamp*$Deleted*$Department*$Description*$DisplayName*$DistinguishedName*$Division*$DoesNotRequirePreAuth*$dSCorePropagationData*$EmailAddress*$EmployeeID*$EmployeeNumber*$employeeType*$Enabled*$Fax*$GivenName*$HomeDirectory*$HomedirRequired*$HomeDrive*$HomePage*$HomePhone*$Initials*$instanceType*$isCriticalSystemObject*$isDeleted*$LastBadPasswordAttempt*$LastKnownParent*$LastLogonDate*$LockedOut*$lockoutTime*$LogonWorkstations*$Manager*$MemberOf*$MNSLogonAccount*$MobilePhone*$Modified*$modifyTimeStamp*$Name*$nTSecurityDescriptor*$ObjectCategory*$ObjectClass*$ObjectGUID*$objectSid*$Office*$OfficePhone*$Organization*$OtherName*$PasswordExpired*$PasswordLastSet*$PasswordNeverExpires*$PasswordNotRequired*$POBox*$PostalCode*$PrimaryGroup*$primaryGroupID*$ProfilePath*$ProtectedFromAccidentalDeletion*$pwdLastSet*$SamAccountName*$sAMAccountType*$ScriptPath*$sDRightsEffective*$ServicePrincipalNames*$SID*$SIDHistory*$SmartcardLogonRequired*$State*$StreetAddress*$Surname*$Title*$TrustedForDelegation*$TrustedToAuthForDelegation*$UseDESKeyOnly*$userAccountControl*$UserPrincipalName*$uSNChanged*$uSNCreated*$whenChanged*$whenCreated" >> $Logfile
        }
[Advertisement] Scout is the best way to monitor your critical server infrastructure. With over 90 open source plugins, robust alerting, beautiful dashboards and a 5 minute install - Scout saves youvaluable engineering time. Try the server monitoring you'll M today.Your first 30 days are free on us. Learn more at Scout.

http://thedailywtf.com/articles/good-idea-bad-idea


Метки:  

Let Them Eat Cookies

Среда, 06 Января 2016 г. 14:30 + в цитатник

As a Python developer, SEO was far outside of Ians toolbox, more in the realm of expensive social media consultants. However, when his friend Alec asked for help, he knew he couldnt turn him down.

Alec worked at LightBarn, a lighting supply company, and was overseeing their SEO optimizations. Alec explained that no one could actually find the companys website with relevant keywords on popular search engines. I looked all the way to page 150! Alec said. I dont get it. We have plenty of inbound links. Alec had worked for months writing a blog on the companys site, and his posts were routinely linked to by other industry sites.

Cookies being cut out of rolled out cookie dough
by Anna reg

Its not my forte, Ian explained, but Im sure I could get LightBarn up to page five, at least. Ian suggested a 20-hour contract to improve the sites page rank. If he couldnt get LightBarn to page five of a typical keyword search, the contract would be terminated. It was win-win for LightBarn, and hed be doing his friend Alec a big favor.

Oddities

Testing the site for any obvious culprits, Ian noticed that LightBarns site was full of oddities. Shopping carts would mysteriously lose items. Search results would be returned in arbitrary orders. He would click on one product and another, unrelated product would be displayed instead.

Ian mentioned these to Alec, who shrugged them off. None of that should affect our page rank. Sure, every website has bugs, but as long as Google can spider our pages it doesnt care.

You sure you dont want my help pinning some of those issues down? Ian offered. I mean, thats my day job.

No, lets stick with the contract language, Alec replied. To Ians ears, it sounded like Alec was more interested in the companys page rank than whether it actually worked for users. Ian decided to ask after it when the existing contract was finished.

But first, he would have to think like a search engine.

Think Like A Bot

Spider bots, Ian knew, are simple creatures programs. They perform an http request for a URL like a typical web browser, scan the returned page content for links, add any matches to a table to scan later, and move on to the next URL to scan. Some use sophisticated search algorithms, such as the ability to determine if a pages content is genuine or if its using keywords to spam search results, but at its core a spider bot just recurively requests pages.

So Ian wrote one himself. Using Pythons http package, he programmed it to accept several different arguments from the command line, such as the URL of origin, what browser ID to use, etc. When he finished, he gave it LightBarns homepage URL for the starting point and let it run.

Just over an hour later, Ian sifted through the saved page files. All of them were under 1KB, way too small for a site like LightBarn, with hundreds of lines of embedded JavaScript and lots of display-centric markup. Opening a few files at random, he noticed that they all contained just one line of text:

Please enable cookies and try again

Crash Diet

Ian explained his test to a bemused Alec later that day. After I saw that, I disabled cookies on my browser to make sure it wasnt just some issue with the http package. When I tried that, every page just displayed the text Please enable cookies and try again.

But we need cookies for session storage, Alec said. Otherwise the shopping cart wont work.

You should only display that message on the shopping cart page. You dont need it across your whole site. Its no wonder search engines dont rank your site  thats the only thing they see when their spiders scan it.

Alec consented to Ians fix. A couple weeks later, Ian noticed that LightBarn was appearing on page 3 or 4 on relevant searches on several popular search engines. Delighted, Alec offered to pay Ian in full for his services.

Actually, Id like to fix some of those other bugs I found at the start of the project, Ian said. As a friend, you may as well get your moneys worth.

[Advertisement] Scout is the best way to monitor your critical server infrastructure. With over 90 open source plugins, robust alerting, beautiful dashboards and a 5 minute install - Scout saves youvaluable engineering time. Try the server monitoring you'll M today.Your first 30 days are free on us. Learn more at Scout.

http://thedailywtf.com/articles/let-them-eat-cookies


Метки:  

CodeSOD: A SASsy Import

Вторник, 05 Января 2016 г. 14:30 + в цитатник

After ten minutes of Mike staring at the screen unmoving, Jill sighed. As the newly minted tech lead, she knew that she had to help unwedge problems. But she also knew that Mike had been tasked with a task which should have been simple, had the project been developed in their team. Alas, it had been thrown over the wall for them to maintain, as a reward for cleaning up so much else.

The calculations for generating quotes for customers were, for some complex scenarios, quoting too low; they were missing some items. The originators of the quote system had used Excel, so there was probably a hard-coded range to be updated. Shed asked Mike to fix it, create a playbook for this system and create a ticket sketching out what might be needed to make the system more resilient and maintainable. Excel would still be required, for the actuaries wouldnt hand over formulae in anything else, but perhaps some jiggling into independent sheets and just running summaries over the whole sheet would reduce the pain. Jill had thoroughly cautioned Mike that he did not want, at this point, to discover the paperwork and bureaucracy to change how the calculations were performed, so the only changes to be made in this first approach were to be the minimum necessary, while keeping the style and solution intact.

What Jill did not expect as the first question from Mike, when she went over, was an inquiry into just what the bureaucracy would be like, to bite the bullet immediately. Humoring him with an explanation, she was somewhat more taken aback when, after only brief cussing, he started pulling up the forms to do so.

Once she saw the code being maintained, and Mikes proposed replacement, she signed off immediately on the paperwork parts she was authorized to approve, and went off with a printed copy to get the co-signatures needed. By the time they were done, the time taken for this override process set a new institutional record for fastest approval. Sometimes, lumbering bureaucracies could move quickly; dodging a bullet during a budgetary crunch with no funding available for empire expansion will do that.

The code, and Mikes replacements, went into training materials for the team. The original code may be found below; it can be summarized as:

  1. Open an instance of Excel and open up a spreadsheet containing details of a single quote
  2. For each of ~160 manually specified cells (almost all from one table on the same sheet in the workbook):
  3. Read the cell contents into a new SAS dataset (as a string of length 50, regardless of whats in the cell).
  4. Merge the new dataset with the one created after processing the previous cell, overwriting the previous one.
  5. Append the dataset for this excel file to the one created for the previous excel file, overwriting the previous one, and close excel.

Mikes replacement:

libname quote excel "\\network\share\folder\file1.xls";
data quote1;
 set quote.summary_table;
run;
libname quote clear;

In a further institutional surprise, when signing off on the new approach, her department head authorized fallback cost-sharing for the internal bean-counting required to pay for the feature license required to make this approach work. She was just asked to not draw attention to this, so that the other group might continue paying themselves, otherwise, theyd be stuck with the original code:

/* scraping macros */
%macro ReadCell(File=,Tab=Quality,Ref=,Col=,FMT=);

 data temp_read;
 run;

 filename ReadC dde "excel|[&file.]&tab.!&Ref." lrecl=500 ;
 data temp_read;
 infile ReadC truncover;
 input &Col. &FMT. ;
 output;
 run;
 filename ReadC clear;

%mend;

%macro MergeNewCell(In=, Out=, New=);
 data &out.;
 merge &in. &new.;
 run;
%mend;
%macro ReadCellMerge(file=,Tab=Quality,Ref=,Col=,FMT=);
 %ReadCell(file=&file.,Tab=&tab.,Ref=&ref.,Col=varname,FMT=&fmt. );
 %MergeNewCell(In=work.temp_scrape, Out=work.temp_scrape, New=temp_read);
%mend;
%macro FindVersion(file=);
 %global QuoteVer;
 %ReadCell(file=&file.,Tab=Version Control,Ref=r9c2,Col=varname,FMT=5.2 );
 data _null_;
 set temp_read;
 call symput("QuoteVer", trim(left(version)));
 run;
%mend;
;

%macro ScrapeQuote(Path=, File=);

 filename ddesys DDE "Excel|system";

/* data _null_;*/
/* file ddesys;*/
/* PUT "[open("'"'"&Path.\&file."'"'",,TRUE)]";*/
/* run;*/

 %OpenExcel( &path.,&file.);

 data work.temp_scrape;
 filename="&path.\&file.";
 run;

 /* quote calculator version */
/* %FindVersion(file=&file.);*/

/* DONT NEED THIS?*/
/* %if &QuoteVer.^=. %then %do; */
/* %ReadCellMerge(file=&file.,Tab=Version Control,Ref=r9c2,Col=varname,FMT=5.2 );*/

 /* SUMMARY */
 %ReadCellMerge(File=&file.,Tab=Summary,Ref=r3c3,Col=varname1,FMT=%nrstr($50.) );
 %ReadCellMerge(File=&file.,Tab=Summary,Ref=r3c4,Col=varname2,FMT=%nrstr($50.) );
 %ReadCellMerge(File=&file.,Tab=Summary,Ref=r3c5,Col=varname3,FMT=%nrstr($50.) );
 %ReadCellMerge(File=&file.,Tab=Summary,Ref=r4c3,Col=varname4,FMT=%nrstr($50.) );
 /*Snipped ~150 similar lines...*/
 %ReadCellMerge(File=&file.,Tab=Summary,Ref=r34c5,Col=varname160,FMT=%nrstr($50.) );

 /* close excel file */
 data _null_;
 file ddesys;
 put "[close("'"'"&Path.\&file."'"'", FALSE)]";
 run;
 filename ddesys clear;

 /* append data */
 data work.scrape_data;
 set work.scrape_data
 work.temp_scrape;
 run;

 /* clean up data from this scrape */
 %symdel QuoteVer;
 data work.temp_scrape;
 if _n_=1 then delete;
 run;

%mend;

/* Scrape!!! */
%ScrapeQuote(Path=%nrbquote(\\network\share\folder), File=%nrbquote(file1.xls));
%ScrapeQuote(Path=%nrbquote(\\network\share\folder), File=%nrbquote(file2.xls));
%ScrapeQuote(Path=%nrbquote(\\network\share\folder), File=%nrbquote(file3.xls));
/*Snipped a large number of manually-written macro calls*/
[Advertisement] BuildMaster is more than just an automation tool: it brings together the people, process, and practices that allow teams to deliver software rapidly, reliably, and responsibly. And it's incredibly easy to get started; download now and use the built-in tutorials and wizards to get your builds and/or deploys automated!

http://thedailywtf.com/articles/a-sassy-import


Метки:  

Announcements: TDWTF API

Понедельник, 04 Января 2016 г. 18:00 + в цитатник

Happy New Year! Have we got some great news for you. Subramanian has contributed a RESTful API for accessing our articles, which weve deployed. So now you can get started on your New Years resolution of writing and sharing more code.

You can check the docs here. I know Subramanian is working on using this to build an Android app, which well be happy to announce here when hes ready. If you use this API for anything, do let us know. And if you have any thoughts for how to improve it, send us a pull request on GitHub. We look forward to seeing the cool stuff you guys get up to with this.

[Advertisement] Scout is the best way to monitor your critical server infrastructure. With over 90 open source plugins, robust alerting, beautiful dashboards and a 5 minute install - Scout saves youvaluable engineering time. Try the server monitoring you'll M today.Your first 30 days are free on us. Learn more at Scout.

http://thedailywtf.com/articles/tdwtf-api


Метки:  

Don't Click That

Понедельник, 04 Января 2016 г. 14:30 + в цитатник

The Big Red Button (3085157011)

The year was 2004, and Scott S. has just begun his internship at IniBank: an underdog financial institution that would, over the years, grow up to be one of the biggest players on the market. Despite being fresh out of college with little experience under his belt, he quickly found his way around the corporate culture and acclimated to the Application Development Department.

His first task was to assist in rewriting a simple, internal Classic ASP application into ASP.NET and WebForms. Eager to work with the then-new and shiny technology, he spent his days researching the documentation, asking questions, and learning the ropes, slowly producing useful code.

One day, as he was tweaking a simple grid, Tim—the project manager and his internship overseer—stepped into his cubicle. "Hi, how's it going?" he asked jovially. "Enjoying the company so far?"

"Sure!" Scott smiled. "The people are nice, the project is pretty cool, and all in all I'm having a good time here."

"Well, I'm glad to hear that, because I've discussed it with the management, and we're thinking of offering you a permanent position."

"Really?" Scott's eyes shone with glee. Straight out of college, and already getting a real job, how cool is that? he thought.

"And how's the rewrite?" Tim asked, taking a seat next to Scott. "Can I see your work?"

"Okay. Today I've been working on the customers view." Scott brought up the project, ran the application, and brought up a simple table. "It's almost done. You can add a person, you can edit their data, but you can't—"

"Hmm, let me see." Tim took the mouse and keyboard from Scott and started testing the application. After adding a few customers and playing with all the sorts and filters on the table, he spotted one more button. "Okay, so now, I click here, and it should delete the customer, right?"

"Um, don't—"

Scott tried to say something, but the cursor was already hovering over the red "Delete" button.

Click.

Now, these days, IniBank has all sorts of test environments and safeguards in place. Back in 2004, however ... to say it wasn't the case was an understatement. In fact, Scott's application was hooked directly to the production environment, running happily with database administrator permissions and ready to wreak havoc.

So when he heard the mouse clicking, his stomach instantly grew as heavy as an iron ball. Because he knew which part of the code he couldn't get to compile, and which part he'd commented out just a few minutes ago ...

"Uh, Scott?" Tim frowned. "Why is the grid empty?"

"I, I ... The WHERE clause ... I'm so sorry," Scott mumbled, his face pale as a sheet of paper, as he frantically tried to remove the filters and change the parameters. But the DELETE statement in his code did its work masterfully—and since it was only half-written, instead of removing the single customer marked for deletion, it simply wiped the whole table.

"You didn't ... oh God!" Tim put two and two together. "Quick, let's call some DBAs and hope there's a current backup!"

Luckily, after a few moments of downtime and a bit of angry shouting, the database was restored. Tim and Scott decided to share the blame and simply forget about this little incident. In the end, Scott got his position at IniBank—and a few years later, after Tim and a few other people left for greener pastures, he became the manager of the now-booming Application Development Department. And while Scott personally made sure a situation like this could never happen again by implementing best practices and proper testing regimes, he still enjoys spooking new developers with an occasional click on the "Delete" button.

[Advertisement] Scout is the best way to monitor your critical server infrastructure. With over 90 open source plugins, robust alerting, beautiful dashboards and a 5 minute install - Scout saves youvaluable engineering time. Try the server monitoring you'll M today.Your first 30 days are free on us. Learn more at Scout.

http://thedailywtf.com/articles/don-t-click-that


Метки:  

Поиск сообщений в rss_thedaily_wtf
Страницы: 124 ... 33 32 [31] 30 29 ..
.. 1 Календарь