#!/usr/bin/python # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. import sys import getopt import json import os import base64 from fcntl import flock, LOCK_EX, LOCK_UN def main(argv): fpath = '' b64data = '' try: opts, args = getopt.getopt(argv, "f:d:") except getopt.GetoptError: print('params: -f -d ') sys.exit(2) for opt, arg in opts: if opt == '-f': fpath = arg elif opt == '-d': b64data = arg json_data = '' if fpath != '': fh = open(fpath, 'r') json_data = json.loads(fh.read()) elif b64data != '': json_data = json.loads(base64.b64decode(b64data)) else: print('-f or -d required') sys.exit(2) for ip in json_data: for item in json_data[ip]: folder = item[0] file = item[1] data = item[2] # process only valid data if folder != "userdata" and folder != "metadata": continue if file == "": continue htaccess(ip, folder, file) if data == "": deletefile(ip, folder, file) else: createfile(ip, folder, file, data) if fpath != '': fh.close() os.remove(fpath) def deletefile(ip, folder, file): datafile = "/var/www/html/" + folder + "/" + ip + "/" + file if os.path.exists(datafile): os.remove(datafile) def writefile(dest, data, mode): fh = open(dest, mode) exflock(fh) fh.write(data) unflock(fh) fh.close() os.chmod(dest, 0o644) def createfile(ip, folder, file, data): dest = "/var/www/html/" + folder + "/" + ip + "/" + file metamanifestdir = "/var/www/html/" + folder + "/" + ip metamanifest = metamanifestdir + "/meta-data" if data is not None: # base64 decode userdata if folder == "userdata" or folder == "user-data": # need to pad data if it is not valid base 64 if len(data) % 4 != 0: data += (4 - (len(data) % 4)) * "=" data = base64.b64decode(data) if isinstance(data, str): writefile(dest, data, "w") elif isinstance(data, bytes): writefile(dest, data, "wb") else: writefile(dest, "", "w") if folder == "metadata" or folder == "meta-data": try: os.makedirs(metamanifestdir, 0o755) except OSError as e: # error 17 is already exists, we do it this way for concurrency if e.errno != 17: print("failed to make directories " + metamanifestdir + " due to :" + e.strerror) sys.exit(1) if os.path.exists(metamanifest): fh = open(metamanifest, "r+a") exflock(fh) if file not in fh.read(): fh.write(file + '\n') unflock(fh) fh.close() else: fh = open(metamanifest, "w") exflock(fh) fh.write(file + '\n') unflock(fh) fh.close() if os.path.exists(metamanifest): os.chmod(metamanifest, 0o644) def htaccess(ip, folder, file): entry = "Options -Indexes\nOrder Deny,Allow\nDeny from all\nAllow from " + ip htaccessFolder = "/var/www/html/" + folder + "/" + ip htaccessFile = htaccessFolder+"/.htaccess" try: os.makedirs(htaccessFolder, 0o755) except OSError as e: # error 17 is already exists, we do it this way for sake of concurrency if e.errno != 17: print("failed to make directories " + htaccessFolder + " due to :" + e.strerror) sys.exit(1) fh = open(htaccessFile, "w") exflock(fh) fh.write(entry + '\n') unflock(fh) fh.close() def exflock(file): try: flock(file, LOCK_EX) except IOError as e: print("failed to lock file" + file.name + " due to : " + e.strerror) sys.exit(1) return True def unflock(file): try: flock(file, LOCK_UN) except IOError as e: print("failed to unlock file" + file.name + " due to : " + e.strerror) sys.exit(1) return True if __name__ == "__main__": main(sys.argv[1:])