Friday, February 27, 2015

Expect the unexpected!

I have been working with linux since Highschool (which isn't as long ago for me as it is for some), and I have just found a new command-line tool!

Expect

I was attempting to automate the 'store user config' process, and the weblogic.Admin way of doing it wasn't behaving(complaining about invalid pad in the key), so I was defaulting back to the WLST command.  I ran into the same problem described here.  Since in my specific scenario, I needed some environment configuration that didn't translate properly, I needed a way to execute it directly in my bash script.

Using the following WLST script (here's the one from StackOverflow above)
#storeUserConfig.py
connect(user1,p@ss,'t3://myhost:9999')
storeUserConfig(userConfigFile='userconfig.secure',userKeyFile='userkey.secure') 
disconnect() 
exit()
I tried piping output directly into the command.... which didn't work!

yes | java -cp $PATH_TO_WEBLOGIC_JAR weblogic.WLST storeUserConfig.py"
and
java -cp $PATH_TO_WEBLOGIC_JAR weblogic.WLST storeUserConfig.py" << EOF
y
EOF

After a coworker suggested "expect", I came up with the following solution...
#createKeyAndConfig.sh

## Do some stuff to set up the env similar to weblogic's included stopWebLogic.sh
...

CMD="java -cp $PATH_TO_WEBLOGIC_JAR weblogic.WLST storeUserConfig.py"

expect -c "
  set timeout -1
  spawn \"$CMD\"
  expect \"y or n\"
  send \"y\r\"
  expect eof
"

The expect command will 'spawn' the java process.  It will wait until it sees the "y or n" portion of output from the script, when it will then 'send' a y followed by a newline to the program.

The first line, 'set timeout -1' was because creating the key file takes longer then the default timeout in expect, so it would terminate early (leaving behind a 0 length userkey.secure file)

Sunday, February 22, 2015

Managing puppet modules with vagrant

A little while ago, I started my journey learning about DevOps, starting out by diving into some of the tooling (Puppet), and adding a few DevOps podcasts into my rotation.

One problem that plagued the process from the beginning... how to handle puppet modules?   Here's the evolution of my thought process...


Stage 1... ignorance

I simple used GIT to control my /etc/puppet/modules/ directory!  Lots of redundant code in here that was already saved in other git repos I could/should just fetch, which gives me an idea...

Stage 2..... frustration
Git Submodules!  I was just manually pulling down most of my modules directly from their git repos instead of though puppet forge anyway, so how about adding them as submodules to my repo, and having git fetch them for me!

Stage 3...... starting automation
Now that I was trying to build easy to run Vagrantfiles that had my puppet configs, I need some way to set it all up....  Initial trick.... adding a 'setup' script in my vagrant directory that pre-downloads all the modules that I run before the first setup! (either by directly calling git clone on the repo, or by calling git submodule init).  This was still a 'prestep' to running vagrant-up, so that didn't quite feel right

Stage 4...... feels right!
One of the first things I did after joining twitter was to ask #puppetize what the best way to manage modules was, and they did not disappoint!  I was redirected to this blog, which shows how you can use puppet librarian to manage your modules, but as to not require everyone to have ruby-gems installed on their main machine, they pull it down inside of their vagrant instance (since most vagrant images already have ruby-gems installed since ruby is a core component of puppet and chef.



Utilizing Configuration management with Vagrant is a powerful tool to help build easily repeatable environments for  both Dev and Deploy!  I hope this helps someone!  I know it was quite a struggle initially!

Saturday, February 14, 2015

Weblogic Identity Asserter and Athorization Provider in one!

When trying to create a Custom Identity Asserter AND Authorization Provider MBean for weblogic, I ran into some trouble..  After following all of the examples, I was unable to get my MBean to behave as both!

While trying to find solutions, my googleFu turned up a few lead that left me feeling like it could not be done.

http://www.ateam-oracle.com/why-do-i-need-an-authenticator-when-i-have-an-identity-asserter/

https://community.oracle.com/thread/796040


 The problem I had was if my MDF file extended IdentityAsserter, it would not contain a method to 'getControlFlag' to pass to the LoginModule.

I found this great example at http://danielveselka.blogspot.com/2011/10/weblogic-custom-identity-asserter.html. The only problem?  He skirts around the same issue by manually assigning a constant value to the controlFlag that gets passed to the AppConfigurationEntry in the getConfiguration() method.  

 public void initialize(ProviderMBean mbean, SecurityServices services)
  {
    System.out.println("SimpleSampleIdentityAsserterProviderImpl.initialize");
    SimpleSampleIdentityAsserterMBean myMBean = (SimpleSampleIdentityAsserterMBean)mbean;
    description  = myMBean.getDescription() + "\n" + myMBean.getVersion();
    
    controlFlag = LoginModuleControlFlag.SUFFICIENT;
...
} 
  private AppConfigurationEntry getConfiguration(HashMap options)
  {
      System.out.println("SimpleSampleIdentityAsserterProviderImpl: getConfiguration");
    // make sure to specify the simple sample authenticator's login module
    // and to use the control flag from the simple sample authenticator's mbean.
    return new
      AppConfigurationEntry(
        "examples.security.providers.authentication.simple.SimpleSampleLoginModuleImpl",
        controlFlag,
        options
      );
  }



In that example, he has the following in the MDF.  If I had this, My MBean would not build with the getControlFlag() method.
 Extends       = "weblogic.management.security.authentication.IdentityAsserter"

If I extended the Authenticator, my assertIdentity() methods from the IdentityAsserter would never get called, but I WOULD have the getControlFlag() method
 Extends       = "weblogic.management.security.authentication.Authenticator"

Turns out this is an easy fix.  There is an attribute value for Implements in the MDF Element Syntax. Having an MBeanType similar to the following solved my problem!

<MBeanType
 Name          = "SimpleSampleIdentityAsserter"
 DisplayName   = "SimpleSampleIdentityAsserter"
 Package       = "examples.security.providers.identityassertion.simple"
 Extends       = "weblogic.management.security.authentication.IdentityAsserter"
 Implements    = "weblogic.management.security.authentication.Authenticator"
 PersistPolicy = "OnUpdate"
>


This allows it to implement all the features of both, but be a single entry that you can add to your weblogic security realm.

Kill-a-watt for 240V appliances?

I've previously used a standard kill-a-watt device to check on power usage around my house.  I wanted to be able to measure more then my standard three prong, 120V receptacles however. 

If you want to measure 240V appliances, I have stumbled across someone who built something to do just that!

If you want to measure things which are hard-wired to your panel, or your whole panel itself, You can look to openenergymonitor.org for information and their shop where you can order any of the parts you would need.  I haven't ordered anything from them yet, but they are based in the UK. 

Sunday, February 1, 2015

Railstutorial, first chapter

I had some spare time today, so I finally got started with the fantastic guy to Ruby on Rails at https://www.railstutorial.org.  I've tried to get started before, but since I'm a bit of a masochist, I've decided to do everything on my raspberry pi.

My last attempt to get started, I told my raspberry pi to install ruby, and it had to build from source.  I left it churn away over night, and that was eventually completed.

Today, I told it to install the rails version specified in the tutorial, and well....

This is what I saw after My wife and I woke up at 3:30 to watch the Australian Open.

While watching, I was able to work my way though the first chapter, deploy locally (to my raspberry pi), to 'production' to a heroku account.

So far it's all been about infrastructure, so I'm looking forward to chapter 2, where you start the 'toy' app so I can begin to see how ruby and rails really work together!