Sunday, September 4, 2022

Today I learned - Dell Server Warranty Lookups

Today I learned - Dell Server Warranty Lookups


In the past, Dell made it hard to access their API for warranty lookups. Even the signup process at https://developer.dell.com/ to get a key was dire - once, they said having 1000 servers wasn't enough to justify API access!


This gist has a working example if you have an API key - https://gist.github.com/teroka/0720274b87b77fe7171f (as well as takes of woe) dealing with the webiste


I also found out that this set of URLs is the one company and it sort of should have a paid option, but doesn't, so I don't understand how it works. I assume they have a Dell API key, or they screen scrpae:

  • http://www.updatewarranty.com
  • http://www.lookupwarranty.com

$ /usr/bin/curl -s --max-time 30 -H "Referer: http://www.lookupwarranty.com/" 'http://www.lookupwarranty.com/updatewarranty/server/lookup?serviceTag=STAGXXX&modelNumber=&mfg=&email=&platform=Website&key' | jq .

{
  "serviceTag": "HT9K6R3",
  "mfg": "Dell",
  "expires": 1234567890,
  "shipped": 1234567890,
  "outOfWarranty": null,
  "error": null,
  "url": "http://www.dell.com/support/my-support/us/en/19/product-support/servicetag/STAGXXX"
}

Tuesday, May 17, 2022

Today I Learned - Power On Linux Server at a Particular Time

So today I learned that it is possible to set an alarm in the future for the motherboard to wake up and a poweroff - and the ability has been around for years (since around 2000)!

This article - https://www.linux.com/training-tutorials/wake-linux-rtc-alarm-clock/ - gives a great demonstration on how to set real time clock wakeup by playing with /sys/class/rtc/rtc0/wakealarm. Some good pointers on cleaning out any BIOS based wake ups as well

This article - https://www.maketecheasier.com/alarm-automatically-power-on-linux/ - introduces the command line tool rtcwake which is a little more user friendly


Wednesday, February 26, 2020

BIND script to create PTR records

BIND script to create PTR records


Just in case you ever need to manage an instance of BIND manually, you will have the pain of remembering to update the PTR records. Here's a quick script to create the PTR records

For those of you that are looking for an alternative, I suggest you use PowerDNS as a backend and PowerDNSAdmin as a nice front end

Here's the script

#!/bin/sh

NETWORKS=$(cat << ENDNET
10.10.1
10.10.2
.
.
.
10.10.99
ENDNET
)

REV_HEADER=$(cat <;
; BIND reverse data file for NETWORK
; Do not edit manually, but run /etc/bin/zones/$0
; after editing /etc/bin/zones/mydomain.tld.db
;
\$TTL    604800
@       IN      SOA     mydns-server.mydomain.tld. root.mydns-server.mydomain.tld. (
                         SERIAL         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
@       IN      NS      mydns-server.mydomain.tld.
END
)

for NETWORK in $NETWORKS ; do
    echo $NETWORK
    NEWSERIAL=`grep Serial db.${NETWORK} | awk '{printf "%6s", $1+1}'`
    echo $NEWSERIAL
    echo "$REV_HEADER" | sed -e "s/SERIAL/$NEWSERIAL/" -e "s/NETWORK/$NETWORK/" > db.${NETWORK}.new
    egrep "$NETWORK\." mydomain.tld.db | grep -v '^;' | awk 'split($4, ipaddr, ".") {printf "%-3s     IN      PTR     %s.mydomain.tld.\n", ipaddr[4], $1}' | sort -n >> db.${NETWORK}.new
    mv db.${NETWORK}.new db.${NETWORK}
done

Wednesday, January 22, 2020

New devices and updating their names with lspci

New devices and updating their names with lspci


We just received a new Exablaze X25 card to review and found lspci was reporting the device as "Exablaze Device 0009"

I just found out that lspci doesn't interrogate the card for the name, but uses a lookup table that can be updated with the update-pciids command, which simply downloads from http://pciids.sourceforge.net/v2.2/pci.ids (on my Ubuntu 16 box), but https://github.com/pciutils/pciids says it takes it from http://pci-ids.ucw.cz/pci.ids.

And here is my X25 card as device 0009:

1ce4  Exablaze
 0001  ExaNIC X4
 0002  ExaNIC X2
 0003  ExaNIC X10
 0004  ExaNIC X10-GM
 0005  ExaNIC X40
 0006  ExaNIC X10-HPT
 0007  ExaNIC X40
 0008  ExaNIC V5P
 0009  ExaNIC X25



Thursday, November 14, 2019

In InSpec You Do not Need a resource to Test


Am using Chef's inspec to validate a server's configuration, and all the examples show you using a resource and testing against a specific set of tests for that resource.

But I am pulling in a YAML file, and want to validate some of the contents (not the YAML itself), so will do that with ruby and return a number of ruby variables I want to test.

The describe block (or here, describe/subject) can just refer to a variable and not an InSpec resource. Here we are checking dups should be an empty array:

control 'validate-nic' do
  impact 0.7
  title 'Validate nic variable structure'
  paths = nic.map{ |k,v| v.dig('path') }
  dups = paths.select{ |e| paths.count(e) > 1 }.uniq

  describe "Check for duplicate path names in nic" do
    subject { dups }
    it { should be_empty }
  end
end


And that works:

Success:
  ✔  validate nic variable structure: Validate nic variable structure
     ✔  Check for duplicate path names in nic should be empty

Failure:

  ×  validate-nic: Validate nic variable structure
     ×  Check for duplicate path names in nic should be empty
     expected `["nic-2-path-a"].empty?` to return true, got false

Monday, October 28, 2019

Puppet 6 - pulling a value from a hiera hash

My favourite data structure is a hash of hashes (of hashes ...)

In Puppet 6, the Hiera replacement lookup allows you access values by defining the key with dot notation. In previous versions you need to extract the whole hash into a manifests and then extract the data from there

Even better you can do that lookup within Hiera itself

profile::private_ssh_keys:   
  '/home/user/.ssh/id_rsa':
    mode: '0600'
    owner: 'user'
    group: 'groupname'
    content: "%{lookup('keybase::sshkeys.my@keyname.private_key')}\n"


Seem more in the Interpolation Functions documentation - https://puppet.com/docs/puppet/6/hiera_merging.html#interpolation_functions

Monday, June 13, 2016

Jenkins Matrix Based Security with Groovy Scripts

So I think I have just wasted a good day or so trying to work out Jenkins 2.x and matrix based authentication via a groovy script

Some googling gives me some good idea on running groovy scripts, but most are just managing the "Overall" section - like Securing jenkins using groovy and chef.

This gave me a framework to get started, but I couldn't work out a pattern for the Credentials/Agent/Job/Run/View/SCM sections. Then this blog post - Automating authentication and authorization on Jenkins - helped me understand the different level names, but it didn't quite fit

I can't quite see how to map permission names to what was available - how to uppercase, what path does the permission live down??

Here's the code - achieved by trial and error - not much understanding...


// http://blog.albertoviana.com/tag/groovy/


import jenkins.model.*
import hudson.security.*
import com.cloudbees.plugins.credentials.*


def instance = Jenkins.getInstance()
def strategy = new GlobalMatrixAuthorizationStrategy()


// Roles based on https://wiki.jenkins-ci.org/display/JENKINS/Matrix-based+security
//Overall - http://javadoc.jenkins-ci.org/jenkins/model/Jenkins.html
strategy.add(Jenkins.ADMINISTER, 'system-account')
strategy.add(Jenkins.RUN_SCRIPTS, 'system-account')
strategy.add(Jenkins.READ, 'system-account')


strategy.add(Jenkins.ADMINISTER, 'admingroup')
strategy.add(Jenkins.RUN_SCRIPTS, 'admingroup')
strategy.add(Jenkins.READ, 'admingroup')


// root# grep anonymous /local/jenkins/config.xml
// hudson.model.Hudson.Read:anonymous
// hudson.model.Item.Read:anonymous
// hudson.model.View.Read:anonymous
strategy.add(Jenkins.READ, 'anonymous')
strategy.add(hudson.model.Item.READ, 'anonymous')
strategy.add(hudson.model.View.READ, 'anonymous')




// Agent (Slave < 2.0) - http://javadoc.jenkins-ci.org/jenkins/model/Jenkins.MasterComputer.html
strategy.add(Jenkins.MasterComputer.BUILD, 'admingroup')
strategy.add(Jenkins.MasterComputer.CONFIGURE, 'admingroup')
strategy.add(Jenkins.MasterComputer.CONNECT, 'admingroup')
strategy.add(Jenkins.MasterComputer.CREATE, 'admingroup')
strategy.add(Jenkins.MasterComputer.DELETE, 'admingroup')
strategy.add(Jenkins.MasterComputer.DISCONNECT, 'admingroup')


// Job - http://javadoc.jenkins-ci.org/hudson/model/Item.html
strategy.add(hudson.model.Item.BUILD, 'admingroup')
strategy.add(hudson.model.Item.CANCEL, 'admingroup')
strategy.add(hudson.model.Item.CONFIGURE, 'admingroup')
strategy.add(hudson.model.Item.CREATE, 'admingroup')
strategy.add(hudson.model.Item.DELETE, 'admingroup')
strategy.add(hudson.model.Item.DISCOVER, 'admingroup')
strategy.add(hudson.model.Item.EXTENDED_READ, 'admingroup')
strategy.add(hudson.model.Item.READ, 'admingroup')
strategy.add(hudson.model.Item.WIPEOUT, 'admingroup')
strategy.add(hudson.model.Item.WORKSPACE, 'admingroup')


// Run - http://javadoc.jenkins-ci.org/hudson/model/Run.html
strategy.add(hudson.model.Run.DELETE, 'admingroup')
strategy.add(hudson.model.Run.UPDATE, 'admingroup')
strategy.add(hudson.model.Run.ARTIFACTS, 'admingroup')


// View - http://javadoc.jenkins-ci.org/hudson/model/View.html
strategy.add(hudson.model.View.CONFIGURE, 'admingroup')
strategy.add(hudson.model.View.CREATE, 'admingroup')
strategy.add(hudson.model.View.DELETE, 'admingroup')
strategy.add(hudson.model.View.READ, 'admingroup')


// SCM - http://javadoc.jenkins-ci.org/hudson/model/View.html
strategy.add(hudson.scm.SCM.TAG, 'admingroup')


// // Credentials - https://github.com/jenkinsci/credentials-plugin/blob/master/src/main/java/com/cloudbees/plugins/credentials/CredentialsProvider.java
// strategy.add(CredentialsProvider.CREATE, "my-user")
// strategy.add(CredentialsProvider.UPDATE, "my-user")
// strategy.add(CredentialsProvider.VIEW, "my-user")
// strategy.add(CredentialsProvider.DELETE, "my-user")
// strategy.add(CredentialsProvider.MANAGE_DOMAINS, "my-user")
//
// Plugin Manager http://javadoc.jenkins-ci.org/hudson/PluginManager.html
//strategy.add(hudson.model.Hudson.UPLOAD_PLUGINS, 'admingroup')
strategy.add(hudson.PluginManager.UPLOAD_PLUGINS, 'admingroup')
strategy.add(hudson.PluginManager.CONFIGURE_UPDATECENTER, 'admingroup')
//
instance.setAuthorizationStrategy(strategy)
instance.save()