DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Deployment
  4. Android Client for Chef: Cyllell

Android Client for Chef: Cyllell

Gareth Llewellyn user avatar by
Gareth Llewellyn
·
Oct. 02, 12 · Interview
Like (0)
Save
Tweet
Share
5.95K Views

Join the DZone community and get the full member experience.

Join For Free

TL;DR; – Download it here.

When you have a server estate the size of DataSift you need a configuration management platform to keep track of what does what, how it is configured and to assist you in rolling out 10 new memcached servers with an identical configuration to the others in production at the drop of a hat. To do that we use Chef from OpsCode.

To interact with Chef you can either use the Web Interface or the CLI client called Knife.

Knife is a powerful command-line interface (CLI) that comes with Chef.
It is used by administrators to interact with the Chef Server API and the local Chef repository. It provides the capability to manipulate nodes, cookbooks, roles, databags, environments, etc., and can also be used to provision cloud resources and to bootstrap systems.


I love CLI’s and prefer them to GUI’s whenever I get the choice but I’m a sucker for writing an Android app if there’s an API available (much like with Rhybudd for Zenoss). So some time ago I set about creating an Android application that could emulate some of the features of Knife from the convenience of your phone.

The biggest hurdle was authenticating with the API as it uses MixLib::Authentication which according to the documentation provides a class-based header signing authentication object. This signed header object is then sent via HTTPS (usually self signed) and has to be within a strict time window.

Looking at the Wiki documentation regarding authenticated API requests it seems quite straight forward but when you discover that versions of Android below 2.2 don’t even have a Base64 encode function you know it’s going to be a bit of a slog.

Making the authenticated headers requires three key steps, first the cryptographic signing of the Headers with your private key;

PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(Base64.decode(this.PrivateKey.getBytes(),0));
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey pk = kf.generatePrivate(spec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
cipher.init(Cipher.ENCRYPT_MODE, pk);
byte[] EncryptedStream = new byte[cipher.getOutputSize(dataToSign.length())];
try
{
 cipher.doFinal(dataToSign.getBytes(),0,dataToSign.length(), EncryptedStream,0);
}
catch (ShortBufferException e)
{
 // TODO Auto-generated catch block
 e.printStackTrace();
}
return Base64.encodeToString(EncryptedStream, Base64.NO_WRAP);

Secondly creating a variety of headers with other information;

Headers.add(new BasicNameValuePair("Accept","application/json"));
Headers.add(new BasicNameValuePair("Content-Type","application/json"));
Headers.add(new BasicNameValuePair("X-Ops-Sign","version=1.0"));
Headers.add(new BasicNameValuePair("X-Ops-Userid",this.ClientName));
Headers.add(new BasicNameValuePair("X-Ops-Timestamp",TimeStamp));
Headers.add(new BasicNameValuePair("X-Ops-Content-Hash",Disgesteriser.hash_string(Body)));
signed_canonicalize_request = SignHeaders("Method:GET"+
"\nHashed Path:" + Disgesteriser.hash_string(Path) +
"\nX-Ops-Content-Hash:"+Disgesteriser.hash_string(Body)+
"\nX-Ops-Timestamp:"+TimeStamp+
"\nX-Ops-UserId:"+this.ClientName);

Finally the cyrptographic signature needs to be added to the headers with the proviso that each line can’t be more than 60 characters;

while(rubyLength < 61 && charLocation < signed_canonicalize_request.length())
{
if(signed_canonicalize_request.charAt(charLocation) != '\n' && signed_canonicalize_request.charAt(charLocation) != '\r')
{
AuthString += signed_canonicalize_request.charAt(charLocation);
rubyLength++;
}
charLocation++;
}
Headers.add(new BasicNameValuePair("X-Ops-Authorization-"+Integer.toString(AuthorizationIteration),AuthString));

With all the authenticating work done getting the information is quite trivial from then on. As described on the OpsCode wiki the API endpoint for a list of cookbooks is simply /cookbooks.

String Path = "/cookbooks";
this.httpget = new HttpGet(this.ChefURL + Path);
List <NameValuePair> Headers = ChefAuth.GetHeaders(Path, "");
for(int i = 0; i < Headers.size(); i++)
{
     this.httpget.setHeader(Headers.get(i).getName(),Headers.get(i).getValue());
}
String jsonTempString = httpClient.execute(this.httpget, responseHandler);

The App is styled in the same manner as the OpsCode website;

A Read Only functionality Beta version is available on Google Play now;

Android app on Google Play

Any feedback can be sent to @NetworkString, Gareth@NetworksAreMadeOfString.co.uk or by sending ICMP packets padded with your suggestion to 2a01:348:18e:2::2

Chef (software) Android (robot)

Published at DZone with permission of Gareth Llewellyn, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • How and Why You Should Start Automating DevOps
  • How to Quickly Build an Audio Editor With UI
  • The Future of Cloud Engineering Evolves
  • Secrets Management

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: