-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
240 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
PLUGINVERSION=1.1.0 | ||
PLUGINVERSION=1.3.0 | ||
PLUGINVERSIONINT="DEV" | ||
PLUGINNAME="metalnx_msi_plugins" |
151 changes: 151 additions & 0 deletions
151
microservices/msirule_deployment/libmsirule_deployment.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
#include "metalnx.h" | ||
#include "metalnx_msi_version.h" | ||
#include "rsModAVUMetadata.hpp" | ||
|
||
#include "rapidjson/document.h" | ||
#include "rapidjson/writer.h" | ||
#include "rapidjson/stringbuffer.h" | ||
#include "rapidjson/filereadstream.h" | ||
#include "rapidjson/filewritestream.h" | ||
#include "rapidjson/prettywriter.h" | ||
|
||
#include <iostream> | ||
#include <boost/foreach.hpp> | ||
#include <boost/property_tree/ptree.hpp> | ||
#include <boost/property_tree/json_parser.hpp> | ||
|
||
#include <boost/filesystem.hpp> | ||
|
||
#define MSI_LOG "[Metalnx Rule Deployment MSI]" | ||
|
||
#define SERVER_CONFIG_FILE "/etc/irods/server_config.json" | ||
#define RULE_DEST_DIR "/etc/irods" | ||
#define PLUGIN_CONFIG_SECTION "plugin_configuration" | ||
#define RULE_ENGINES_SECTION "rule_engines" | ||
#define PLUGIN_SPECIFIC_CONFIG_SECTION "plugin_specific_configuration" | ||
#define RULEBASE_SET_SECTION "re_rulebase_set" | ||
#define RULE_FILE_EXTENSION ".re" | ||
#define BUFFER_SIZE 65536 | ||
|
||
using namespace boost::filesystem; | ||
using namespace rapidjson; | ||
|
||
using boost::property_tree::ptree; | ||
using boost::property_tree::read_json; | ||
using boost::property_tree::write_json; | ||
|
||
extern "C" { | ||
|
||
void add_rule_to_base_set(char* rule_filename) { | ||
rodsLog(LOG_NOTICE, "%s Add rule to base set [%s]\n", MSI_LOG, rule_filename, SERVER_CONFIG_FILE); | ||
|
||
FILE* fp = fopen(SERVER_CONFIG_FILE, "rb"); | ||
char readBuffer[BUFFER_SIZE]; | ||
FileReadStream is(fp, readBuffer, sizeof(readBuffer)); | ||
|
||
Document document; | ||
document.ParseStream(is); | ||
|
||
fclose(fp); | ||
|
||
rodsLog(LOG_NOTICE, "%s Adding rule [%s] to the server config base set [%s]\n", MSI_LOG, rule_filename, SERVER_CONFIG_FILE); | ||
Document::AllocatorType& allocator = document.GetAllocator(); | ||
Value& array = document["plugin_configuration"]["rule_engines"][0]["plugin_specific_configuration"]["re_rulebase_set"]; | ||
array.PushBack(StringRef(""), allocator); | ||
for (SizeType i = array.Size()-1; i > 0u; --i) | ||
array[i] = array[i-1]; | ||
array[0] = StringRef(rule_filename); | ||
|
||
rodsLog(LOG_NOTICE, "%s Saving new server config file\n", MSI_LOG); | ||
fp = fopen(SERVER_CONFIG_FILE, "wb"); | ||
char writeBuffer[BUFFER_SIZE]; | ||
FileWriteStream os(fp, writeBuffer, sizeof(writeBuffer)); | ||
PrettyWriter<FileWriteStream> writer(os); | ||
document.Accept(writer); | ||
fclose(fp); | ||
rodsLog(LOG_NOTICE, "%s Server config file saved\n", MSI_LOG); | ||
|
||
rodsLog(LOG_NOTICE, "%s Added rule [%s] to the server config base set [%s]\n", MSI_LOG, rule_filename, SERVER_CONFIG_FILE); | ||
} | ||
|
||
/** | ||
* Copies a file from a source path in iRODS to a destination path. | ||
*/ | ||
bool copy_file_from_irods(const char* src_path, const char* dest_path) { | ||
rodsLog(LOG_NOTICE, "%s Copying file from [%s] to [%s]\n", MSI_LOG, src_path, dest_path); | ||
|
||
path from (src_path); | ||
|
||
if (!is_regular_file(from)) { | ||
rodsLog(LOG_ERROR, "%s Source file [%s] is not a regular file\n", MSI_LOG, src_path); | ||
return false; | ||
} | ||
|
||
std::ifstream src(src_path, std::ios::binary); | ||
std::ofstream dst(dest_path, std::ios::binary); | ||
|
||
dst << src.rdbuf(); | ||
|
||
rodsLog(LOG_NOTICE, "%s Copied file from [%s] to [%s]\n", MSI_LOG, src_path, dest_path); | ||
return true; | ||
} | ||
|
||
const char* get_rule_dst_path(char* rule_name) { | ||
std::string rule_dst_dir (RULE_DEST_DIR); | ||
std::string rule_dst_file (rule_name); | ||
std::string rule_dst_path = rule_dst_dir + "/" + rule_dst_file; | ||
return rule_dst_path.c_str(); | ||
} | ||
|
||
int msirule_deployment(msParam_t* inRuleNameParam, msParam_t* inRuleFilePathParam, ruleExecInfo_t* rei ) { | ||
rodsLog(LOG_NOTICE, "%s MSI Rule Deployment [%s]\n", MSI_LOG, MSI_VERSION); | ||
|
||
char* rule_name = (char*) inRuleNameParam->inOutStruct; | ||
char* rule_src_path = (char*) inRuleFilePathParam->inOutStruct; | ||
|
||
rodsLog(LOG_NOTICE, "%s Deploying rule [%s]\n", MSI_LOG, rule_name); | ||
|
||
// copy the rule file from the source path into the /etc/irods directory | ||
std::string rule_dst_dir (RULE_DEST_DIR); | ||
std::string rule_dst_file (rule_name); | ||
rule_dst_file = rule_dst_file + RULE_FILE_EXTENSION; | ||
std::string rule_dst_path = rule_dst_dir + "/" + rule_dst_file; | ||
if(!copy_file_from_irods(rule_src_path, rule_dst_path.c_str())) { | ||
return MSI_ERROR; | ||
} | ||
|
||
// add the new rule into the server config file | ||
add_rule_to_base_set(rule_name); | ||
|
||
return MSI_SUCCESS; | ||
} | ||
|
||
// =-=-=-=-=-=-=- | ||
// plugin factory | ||
irods::ms_table_entry* plugin_factory( ) { | ||
// =-=-=-=-=-=-=- | ||
// instantiate a new msvc plugin | ||
irods::ms_table_entry* msvc = new irods::ms_table_entry( 2 ); | ||
|
||
// =-=-=-=-=-=-=- | ||
// wire the implementation to the plugin instance | ||
msvc->add_operation< | ||
msParam_t*, | ||
msParam_t*, | ||
ruleExecInfo_t*>("msirule_deployment", | ||
std::function<int( | ||
msParam_t*, | ||
msParam_t*, | ||
ruleExecInfo_t*)>(msirule_deployment)); | ||
|
||
// =-=-=-=-=-=-=- | ||
// hand it over to the system | ||
return msvc; | ||
|
||
} // plugin_factory | ||
|
||
} // extern "C" | ||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
mlxRuleDeployment { | ||
msirule_deployment(*rule_name, *rule_file_path); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
acPostProcForPut { | ||
writeLine("serverLog", "Testing rules deployment\n"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import json | ||
from os.path import join, dirname, realpath, exists | ||
from unittest import TestCase, main | ||
|
||
from tests import MetadataExtractConfig, iput, irm, _call | ||
|
||
|
||
def load_server_config_as_json(path): | ||
""" | ||
Loads the iRODS server config file as JSON | ||
:param path: path to the server config file (typically under /etc/irods) | ||
:return: server config file content as JSON | ||
""" | ||
with open(path, 'r') as server_config_fp: | ||
server_config_json = json.loads(server_config_fp.read()) | ||
return server_config_json | ||
|
||
|
||
def get_rule_base_set_from_config(server_config_json): | ||
""" | ||
Finds the rule base set section in the iRODS server config file | ||
:param server_config_json: iRODS server config file as JSON | ||
:return: the 're_rulebase_set' JSON section (array) | ||
""" | ||
|
||
# plugin_config > rule_engines > first array item > plugin_spec_config > re_rulebase_set | ||
rule_base_set = server_config_json['plugin_configuration']['rule_engines'][0]['plugin_specific_configuration'][ | ||
're_rulebase_set'] | ||
return rule_base_set | ||
|
||
|
||
class TestRuleDeployment(TestCase, MetadataExtractConfig): | ||
def setUp(self): | ||
self.rule_file_path = join(self.VAULT_ROOT_PATH, self.RULE_CACHE_DIR_NAME, self.RULE_DEPLOYMENT_FILE_NAME) | ||
self.rule_obj_path = '{}/{}'.format(self.RULE_CACHE_IRODS_PATH, self.RULE_DEPLOYMENT_FILE_NAME) | ||
|
||
self.cleanUp() | ||
|
||
local_rule_file = join(dirname(realpath(__file__)), 'samples', self.RULE_DEPLOYMENT_FILE_NAME) | ||
iput(local_rule_file, self.RULE_CACHE_IRODS_PATH) # iput file into /tempZone/.rulecache | ||
|
||
def test_deploy_rule(self): | ||
self.call_rule_deployment(rule_name=self.RULE_DEPLOYMENT_FILE_NAME[:-3], rule_file_path=self.rule_file_path) | ||
self.assertTrue(exists(join(self.IRODS_ETC_DIR, self.RULE_DEPLOYMENT_FILE_NAME))) | ||
|
||
server_config_json = load_server_config_as_json(self.IRODS_SERVER_CONFIG_PATH) | ||
rule_base_set = get_rule_base_set_from_config(server_config_json) | ||
|
||
self.assertTrue(self.RULE_DEPLOYMENT_FILE_NAME[:-3] in rule_base_set) # rule must be present in the config file | ||
self.assertEqual(self.RULE_DEPLOYMENT_FILE_NAME[:-3], rule_base_set[0]) # rule must be the first one in the list | ||
|
||
def tearDown(self): | ||
self.cleanUp() | ||
|
||
def cleanUp(self): | ||
irm('-rf', self.rule_obj_path) # remove file from iRODS | ||
_call('rm', '-rf', self.rule_file_path) # remove file from local file system | ||
_call('rm', '-rf', join(self.IRODS_ETC_DIR, self.RULE_DEPLOYMENT_FILE_NAME)) # remove rule from /etc/irods | ||
|
||
if __name__ == '__main__': | ||
main() |