#!/usr/bin/python3
import argparse
import os
import requests
import ipaddress
import re
import sys
if __name__ == "__main__" :
os . chdir ( os . path . dirname ( sys . argv [ 0 ]))
parser = argparse . ArgumentParser ()
parser . add_argument ( '-i' , '--ip_address' , help = 'The IP address you want to set for the machine' , required = True )
parser . add_argument ( '-s' , '--subnet' , help = 'The IP address you want to set for the machine' , required = True )
parser . add_argument ( '-d' , '--dns_server' , help = 'The IP address you want to set for the machine' , required = True )
parser . add_argument ( '-g' , '--gateway' , help = 'The IP address you want to set for the machine' , required = True )
parser . add_argument ( '-n' , '--hostname' , help = 'The hostname you want to set for the machine' , required = True )
parser . add_argument ( '-m' , '--mntpoint' , help = 'The mount point of your SD card. Do not add a trailing / to the path' , required = True )
parser . add_argument ( '-u' , '--username' , help = 'The user name of the user you wish to add SSH keys to' , required = True )
parser . add_argument ( '-o' , '--operating_system' , help = 'Distribution for template files' , choices = [ 'ubuntu' ], required = True )
arggroup = parser . add_mutually_exclusive_group ()
arggroup . add_argument ( '-k' , '--ssh_pubkey_file' , help = 'A public key SSH file' )
arggroup . add_argument ( '-gh' , '--github_pubkeys' , help = 'Public keys from a Github account that you want to allow onto the machine' )
args = parser . parse_args ()
# Check the mount point
if not os . path . exists ( args . mntpoint ):
exit ( 1 , f 'The mount point provided is not valid. \n MOUNT POINT: \n { args . mntpoint } ' )
# Retrieve the public key
if args . github_pubkeys :
r = requests . get ( f 'https://github.com/ { args . github_pubkeys } .keys' )
if r . status_code == 200 :
pubkey = r . content . decode ()
else :
exit ( 1 , 'Could not find the Github user' )
else :
if not os . path . isfile ( args . ssh_pubkey_file ):
exit ( 1 , 'Could not find the public key file' )
with open ( args . ssh_pubkey_file , 'r' ) as file :
pubkey = file . read ()
# Validate IP, subnet and DNS server
try :
ipaddress . ip_address ( args . ip_address )
except ValueError :
exit ( 1 , 'The IP provided is not valid IP' )
try :
ipaddress . ip_address ( args . subnet )
except ValueError :
exit ( 1 , 'The subnet provided is not valid' )
try :
ipaddress . ip_address ( args . dns_server )
except ValueError :
exit ( 1 , 'The DNS server provided is not valid IP' )
# Read the resolve template
with open ( f 'templates/ { args . operating_system } /resolv.conf' , 'r' ) as dns_template :
file_contents = dns_template . read ()
text = re . sub ( '<DNSSERVER>' , args . dns_server , file_contents )
# Write the resolv file
with open ( f ' { args . mntpoint } /etc/resolv.conf' , 'w' ) as dns_target :
dns_target . write ( text )
# Read the interface file template
with open ( f 'templates/ { args . operating_system } /interfaces' , 'r' ) as interface_template :
file_contents = interface_template . read ()
text = re . sub ( '<IPADDRESS>' , args . ip_address , file_contents )
text = re . sub ( '<SUBNETMASK>' , args . subnet , text )
text = re . sub ( '<GATEWAY>' , args . gateway , text )
text = re . sub ( '<DNSSERVER>' , args . dns_server , text )
# Write the interfaces file
with open ( f ' { args . mntpoint } /etc/network/interfaces' , 'w' ) as interface_target :
interface_target . write ( text )
# Write the hostname
with open ( f ' { args . mntpoint } /etc/hostname' , 'w' ) as interface_target :
interface_target . write ( args . hostname )
# Write the hosts file
with open ( f 'templates/ { args . operating_system } /hosts' , 'r' ) as hosts_template :
hosts = hosts_template . read ()
# Sort between hostnames and FQDN
if args . hostname in '.' :
text = re . sub ( '<HOSTNAME>' , f " { str ( args . hostname ). split ( '.' )[ 0 ] } { args . hostname } " , hosts )
else :
text = re . sub ( '<HOSTNAME>' , f ' { args . hostname } ' , hosts )
with open ( f ' { args . mntpoint } /etc/hosts' , 'w' ) as hosts_target :
hosts_target . write ( text )
# Check for .ssh folder in the users home dir
if not os . path . exists ( f ' { args . mntpoint } /home/ { args . username } /.ssh' ):
os . makedirs ( f ' { args . mntpoint } /home/ { args . username } /.ssh' )
# Write the authorized_keys file
with open ( f ' { args . mntpoint } /home/ { args . username } /.ssh/authorized_keys' , 'w' ) as authed_keys :
authed_keys . write ( pubkey )
# Set RO permissions on authorized_keys file
os . chmod ( f ' { args . mntpoint } /home/ { args . username } /.ssh/authorized_keys' , 0o444 )
print ( "Template files written successfully. Eject the SD and happy pi'ing" )