diff --git a/.copr/Makefile b/.copr/Makefile index eb68b3e91a..6fc6d09519 100644 --- a/.copr/Makefile +++ b/.copr/Makefile @@ -59,6 +59,7 @@ srpm: iml-sfa.service \ ${TMPDIR}/release/rust-iml cp ${TARGET}/release/iml ${TMPDIR}/release/rust-iml + cp ${TARGET}/release/iml-config ${TMPDIR}/release/rust-iml tar -czvf ${TMPDIR}/_topdir/SOURCES/rust-iml.tar.gz -C ${TMPDIR}/release/rust-iml . cp rust-iml.spec ${TMPDIR}/_topdir/SPECS/ rpmbuild -bs -D "_topdir ${TMPDIR}/_topdir" ${TMPDIR}/_topdir/SPECS/rust-iml.spec @@ -96,6 +97,7 @@ iml-srpm: iml-deps substs cp ${BUILDROOT}/python-iml-manager.spec ${TMPDIR}/_topdir/SPECS cp -r ${BUILDROOT}/grafana ${TMPDIR}/configuration + cp -r ${BUILDROOT}/nginx ${TMPDIR}/configuration cp ${BUILDROOT}/iml-*.service \ ${BUILDROOT}/rabbitmq-env.conf \ ${BUILDROOT}/rabbitmq-server-dropin.conf \ diff --git a/Cargo.lock b/Cargo.lock index a1aae0f5f3..db48b3e80f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1399,8 +1399,11 @@ dependencies = [ "iml-tracing", "iml-wire-types", "indicatif", + "insta", + "lazy_static", "number-formatter", "prettytable-rs", + "regex", "reqwest", "serde", "serde_json", diff --git a/chroma_core/lib/service_config.py b/chroma_core/lib/service_config.py index 162d5fe4de..b224359d1d 100644 --- a/chroma_core/lib/service_config.py +++ b/chroma_core/lib/service_config.py @@ -676,40 +676,6 @@ def _configure_firewall(self): self.try_shell(["firewall-cmd", "--permanent", "--add-port={}/tcp".format(port)]) self.try_shell(["firewall-cmd", "--add-port={}/tcp".format(port)]) - def set_nginx_config(self): - project_dir = os.path.dirname(os.path.realpath(settings.__file__)) - conf_template = os.path.join(project_dir, "chroma-manager.conf.template") - - nginx_settings = [ - "REPO_PATH", - "HTTP_FRONTEND_PORT", - "HTTPS_FRONTEND_PORT", - "HTTP_AGENT_PROXY_PASS", - "HTTP_AGENT2_PROXY_PASS", - "HTTP_API_PROXY_PASS", - "IML_API_PROXY_PASS", - "WARP_DRIVE_PROXY_PASS", - "MAILBOX_PATH", - "MAILBOX_PROXY_PASS", - "SSL_PATH", - "DEVICE_AGGREGATOR_PORT", - "DEVICE_AGGREGATOR_PROXY_PASS", - "UPDATE_HANDLER_PROXY_PASS", - "GRAFANA_PORT", - "GRAFANA_PROXY_PASS", - "INFLUXDB_PROXY_PASS", - "TIMER_PROXY_PASS", - "INCLUDES", - ] - - with open(conf_template, "r") as f: - config = f.read() - for setting in nginx_settings: - config = config.replace("{{%s}}" % setting, str(getattr(settings, setting))) - - with open("/etc/nginx/conf.d/chroma-manager.conf", "w") as f2: - f2.write(config) - def _register_profiles(self): for x in glob.glob("/usr/share/chroma-manager/*.profile"): print("Registering profile: {}".format(x)) @@ -793,8 +759,6 @@ def setup(self, username, password, ntp_server, check_db_space): self._configure_selinux() self._configure_firewall() - self.set_nginx_config() - self._setup_influxdb() error = self._setup_database(check_db_space) diff --git a/chroma_core/management/commands/print-settings.py b/chroma_core/management/commands/print-settings.py index 9b5da79dad..ff2ced2fb2 100644 --- a/chroma_core/management/commands/print-settings.py +++ b/chroma_core/management/commands/print-settings.py @@ -29,10 +29,23 @@ def handle(self, *args, **kwargs): "WARP_DRIVE_PORT": settings.WARP_DRIVE_PORT, "MAILBOX_PORT": settings.MAILBOX_PORT, "DEVICE_AGGREGATOR_PORT": settings.DEVICE_AGGREGATOR_PORT, + "HTTP_FRONTEND_PORT": settings.HTTP_FRONTEND_PORT, + "HTTPS_FRONTEND_PORT": settings.HTTPS_FRONTEND_PORT, + "HTTP_AGENT_PROXY_PASS": settings.HTTP_AGENT_PROXY_PASS, "HTTP_AGENT2_PORT": settings.HTTP_AGENT2_PORT, "HTTP_AGENT2_PROXY_PASS": settings.HTTP_AGENT2_PROXY_PASS, + "HTTP_API_PROXY_PASS": settings.HTTP_API_PROXY_PASS, "IML_API_PORT": settings.IML_API_PORT, "IML_API_PROXY_PASS": settings.IML_API_PROXY_PASS, + "WARP_DRIVE_PROXY_PASS": settings.WARP_DRIVE_PROXY_PASS, + "MAILBOX_PROXY_PASS": settings.MAILBOX_PROXY_PASS, + "SSL_PATH": settings.SSL_PATH, + "DEVICE_AGGREGATOR_PROXY_PASS": settings.DEVICE_AGGREGATOR_PROXY_PASS, + "UPDATE_HANDLER_PROXY_PASS": settings.UPDATE_HANDLER_PROXY_PASS, + "GRAFANA_PORT": settings.GRAFANA_PORT, + "GRAFANA_PROXY_PASS": settings.GRAFANA_PROXY_PASS, + "INFLUXDB_PROXY_PASS": settings.INFLUXDB_PROXY_PASS, + "TIMER_PROXY_PASS": settings.TIMER_PROXY_PASS, "ALLOW_ANONYMOUS_READ": json.dumps(settings.ALLOW_ANONYMOUS_READ), "BUILD": settings.BUILD, "IS_RELEASE": json.dumps(settings.IS_RELEASE), @@ -53,6 +66,7 @@ def handle(self, *args, **kwargs): "DB_NAME": DB.get("NAME"), "DB_USER": DB.get("USER"), "DB_PASSWORD": DB.get("PASSWORD"), + "REPO_PATH": settings.REPO_PATH, "AMQP_BROKER_USER": settings.AMQP_BROKER_USER, "AMQP_BROKER_PASSWORD": settings.AMQP_BROKER_PASSWORD, "AMQP_BROKER_VHOST": settings.AMQP_BROKER_VHOST, @@ -61,6 +75,7 @@ def handle(self, *args, **kwargs): "AMQP_BROKER_URL": settings.BROKER_URL, "BRANDING": settings.BRANDING, "USE_STRATAGEM": settings.USE_STRATAGEM, + "INCLUDES": settings.INCLUDES, } if settings.EXA_VERSION: diff --git a/iml-manager-cli/Cargo.toml b/iml-manager-cli/Cargo.toml index 75c2db57c4..c2bacbac57 100644 --- a/iml-manager-cli/Cargo.toml +++ b/iml-manager-cli/Cargo.toml @@ -18,8 +18,10 @@ iml-orm = { path = "../iml-orm", version = "0.3", features = ["postgres-interop" iml-tracing = { version = "0.2", path="../iml-tracing"} iml-wire-types = { path = "../iml-wire-types", version = "0.3" } indicatif = "0.14" +lazy_static = "1.4" number-formatter = { path = "../number-formatter", version = "0.1" } prettytable-rs = "0.8" +regex = "1.3" reqwest = { version = "0.10", features = ["default-tls", "json"] } serde = { version = "1", features = ["derive"] } serde_json = "1" @@ -27,9 +29,16 @@ serde_yaml = "0.8" spinners = "1.2.0" structopt = "0.3" thiserror = "1.0" -tokio = { version = "0.2", features = ["macros", "io-std", "io-util"] } +tokio = { version = "0.2", features = ["macros", "io-std", "io-util", "fs"] } tracing = "0.1" +[dev-dependencies] +insta = "0.16" + [[bin]] name = "iml" path = "src/main.rs" + +[[bin]] +name = "iml-config" +path = "src/config-main.rs" \ No newline at end of file diff --git a/iml-manager-cli/src/config-main.rs b/iml-manager-cli/src/config-main.rs new file mode 100644 index 0000000000..851578ded3 --- /dev/null +++ b/iml-manager-cli/src/config-main.rs @@ -0,0 +1,42 @@ +// Copyright (c) 2020 DDN. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +use iml_manager_cli::{ + display_utils::display_error, + nginx::{self, nginx_cli}, +}; +use std::process::exit; +use structopt::StructOpt; + +#[derive(Debug, StructOpt)] +#[structopt(name = "iml-config", setting = structopt::clap::AppSettings::ColoredHelp)] +/// The IML Config CLI +pub enum App { + #[structopt(name = "nginx")] + /// Nginx config file generator + Nginx { + #[structopt(subcommand)] + command: nginx::NginxCommand, + }, +} + +#[tokio::main] +async fn main() -> Result<(), Box> { + iml_tracing::init(); + + let matches = App::from_args(); + + tracing::debug!("Matching args {:?}", matches); + + let r = match matches { + App::Nginx { command } => nginx_cli(command).await, + }; + + if let Err(e) = r { + display_error(e); + exit(1); + } + + Ok(()) +} diff --git a/iml-manager-cli/src/error.rs b/iml-manager-cli/src/error.rs index 5a7a16daec..5c5ec310d9 100644 --- a/iml-manager-cli/src/error.rs +++ b/iml-manager-cli/src/error.rs @@ -63,6 +63,7 @@ pub enum ImlManagerCliError { CombineEasyError(combine::stream::easy::Errors), DoesNotExist(&'static str), FailedCommandError(Vec), + FromUtf8Error(#[from] std::string::FromUtf8Error), ImlOrmError(#[from] iml_orm::ImlOrmError), IntParseError(#[from] std::num::ParseIntError), IoError(#[from] std::io::Error), @@ -90,6 +91,7 @@ impl std::fmt::Display for ImlManagerCliError { write!(f, "{}", failed_msg) } + ImlManagerCliError::FromUtf8Error(ref err) => write!(f, "{}", err), ImlManagerCliError::ImlOrmError(ref err) => write!(f, "{}", err), ImlManagerCliError::IntParseError(ref err) => write!(f, "{}", err), ImlManagerCliError::IoError(ref err) => write!(f, "{}", err), diff --git a/iml-manager-cli/src/lib.rs b/iml-manager-cli/src/lib.rs index 6ded6a1426..e7a85e184a 100644 --- a/iml-manager-cli/src/lib.rs +++ b/iml-manager-cli/src/lib.rs @@ -6,6 +6,7 @@ pub mod api_utils; pub mod display_utils; pub mod error; pub mod filesystem; +pub mod nginx; pub mod ostpool; pub mod profile; pub mod server; diff --git a/iml-manager-cli/src/nginx.rs b/iml-manager-cli/src/nginx.rs new file mode 100644 index 0000000000..74ad0e790a --- /dev/null +++ b/iml-manager-cli/src/nginx.rs @@ -0,0 +1,136 @@ +// Copyright (c) 2020 DDN. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +use crate::error::ImlManagerCliError; +use console::Term; +use lazy_static::*; +use regex::{Captures, Regex}; +use std::{collections::HashMap, env, str}; +use structopt::StructOpt; +use tokio::fs; + +#[derive(Debug, StructOpt)] +pub enum NginxCommand { + /// Generate Nginx conf + #[structopt(name = "generate-config")] + GenerateConfig { + /// Set the nginx config path + #[structopt(short = "p", long = "path")] + template_path: String, + + #[structopt(short = "o", long = "output")] + output_path: Option, + }, +} + +fn replace_template_variables(contents: &str, vars: HashMap) -> String { + lazy_static! { + static ref RE: Regex = Regex::new(r"(\{\{\w+\}\})").unwrap(); + } + + let config: String = contents + .lines() + .map(|l| { + RE.replace_all(l, |caps: &Captures| { + let key = &caps[1].replace("{", "").replace("}", ""); + let val = vars + .get(key) + .unwrap_or_else(|| panic!("{} variable not set", key)); + + caps[0].replace(&caps[1], &val) + }) + .to_string() + }) + .collect::>() + .join("\n"); + + config +} + +pub async fn nginx_cli(command: NginxCommand) -> Result<(), ImlManagerCliError> { + match command { + NginxCommand::GenerateConfig { + template_path, + output_path, + } => { + let nginx_template_bytes = fs::read(template_path).await?; + let nginx_template = String::from_utf8(nginx_template_bytes)?; + + let vars: HashMap = env::vars().collect(); + + let config = replace_template_variables(&nginx_template, vars); + + if let Some(path) = output_path { + fs::write(path, config).await?; + } else { + let term = Term::stdout(); + + iml_tracing::tracing::debug!("Nginx Config: {}", config); + + term.write_line(&config).unwrap(); + } + } + }; + + Ok(()) +} + +#[cfg(test)] +mod tests { + use super::*; + use insta::*; + use std::collections::HashMap; + + #[test] + fn test_replace_template_variables() { + let template: &[u8] = include_bytes!("../../chroma-manager.conf.template"); + + let vars: HashMap = [ + ("REPO_PATH", "/var/lib/chroma/repo"), + ("HTTP_FRONTEND_PORT", "80"), + ("HTTPS_FRONTEND_PORT", "443"), + ("HTTP_AGENT_PROXY_PASS", "http://127.0.0.1:8002"), + ("HTTP_AGENT2_PROXY_PASS", "http://127.0.0.1:8003"), + ("HTTP_API_PROXY_PASS", "http://127.0.0.1:8001"), + ("IML_API_PROXY_PASS", "http://127.0.0.1:8004"), + ("WARP_DRIVE_PROXY_PASS", "http://127.0.0.1:8890"), + ("MAILBOX_PATH", "/var/spool/iml/mailbox"), + ("MAILBOX_PROXY_PASS", "http://127.0.0.1:8891"), + ("SSL_PATH", "/var/lib/chroma"), + ("DEVICE_AGGREGATOR_PORT", "8008"), + ("DEVICE_AGGREGATOR_PROXY_PASS", "http://127.0.0.1:8008"), + ( + "UPDATE_HANDLER_PROXY_PASS", + "http://unix:/var/run/iml-update-handler.sock", + ), + ("GRAFANA_PORT", "3000"), + ("GRAFANA_PROXY_PASS", "http://127.0.0.1:3000"), + ("INFLUXDB_PROXY_PASS", "http://127.0.0.1:8086"), + ("TIMER_PROXY_PASS", "http://127.0.0.1:8892"), + ("INCLUDES", ""), + ] + .iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(); + + let config = replace_template_variables( + &str::from_utf8(template).expect("Couldn't parse template"), + vars, + ); + + assert_display_snapshot!(config); + } + + #[test] + fn test_multiple_replacements() { + let vars: HashMap = [("FOO", "foo"), ("BAR", "bar")] + .iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(); + + let cfg = replace_template_variables("{{FOO}}/{{BAR}}", vars); + + assert_eq!(cfg, "foo/bar"); + } +} diff --git a/iml-manager-cli/src/snapshots/iml_manager_cli__nginx__tests__replace_template_variables.snap b/iml-manager-cli/src/snapshots/iml_manager_cli__nginx__tests__replace_template_variables.snap new file mode 100644 index 0000000000..f246cc3a1d --- /dev/null +++ b/iml-manager-cli/src/snapshots/iml_manager_cli__nginx__tests__replace_template_variables.snap @@ -0,0 +1,413 @@ +--- +source: iml-manager-cli/src/nginx.rs +expression: config +--- +map $ssl_client_s_dn $ssl_client_s_dn_cn { + default ""; + ~CN=(?[^,]+) $CN; +} + +map $status $loggable { + ~^[23] 0; + default 1; +} + +map $uri $cache_control { + default no-cache; + ~\.html$ public,must-revalidate; + ~\.(jpg|jpeg|png|gif|ico|css|js|wasm|woff2|svg)$ public,max-age=31536000,immutable; +} + +server { + listen 443 ssl http2; + + error_page 497 https://$http_host$request_uri; + + proxy_read_timeout 330s; + + access_log /var/log/nginx/access.log combined if=$loggable; + + types { + application/javascript js; + application/json json map; + application/manifest+json webmanifest; + application/octet-stream bin exe dll; + application/octet-stream deb; + application/octet-stream dmg; + application/octet-stream eot; + application/octet-stream iso img; + application/octet-stream msi msp msm; + application/wasm wasm; + application/x-makeself run; + application/x-pilot prc pdb; + application/x-rar-compressed rar; + application/x-redhat-package-manager rpm; + application/x-shockwave-flash swf; + application/x-tcl tcl tk; + application/x-x509-ca-cert der pem crt; + application/zip zip; + font/woff woff; + font/woff2 woff2; + image/gif gif; + image/jpeg jpeg jpg; + image/png png; + image/svg+xml svg; + image/x-icon ico; + text/css css; + text/html html htm; + text/plain txt; + text/x-component htc; + text/xml xml rss; + } + + ssl_certificate /var/lib/chroma/manager.crt; + ssl_certificate_key /var/lib/chroma/manager.pem; + ssl_trusted_certificate /var/lib/chroma/authority.crt; + ssl_client_certificate /var/lib/chroma/authority.crt; + ssl_verify_client optional; + ssl_protocols TLSv1.2; + ssl_prefer_server_ciphers on; + ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:!DH+3DES:!ADH:!AECDH:!RC4:!aNULL:!MD5'; + + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 180m; + + gzip_comp_level 5; + + location /favicon.ico { + alias /usr/lib/iml-manager/iml-gui/favicon.ico; + } + + location /certificate/ { + return 301 https://$http_host/certificate; + } + + location /certificate { + alias /var/lib/chroma/authority.crt; + types {} + default_type application/octet-stream; + add_header Content-disposition "attachment; filename=download.cer"; + } + + location ~ ^/$ { + return 301 https://$http_host/ui; + } + + location /help { + alias /usr/lib/iml-manager/iml-online-help; + + gzip on; + gzip_types text/plain text/xml text/css application/x-javascript application/javascript text/javascript application/json; + + index index.html; + } + + # This is temporary until the /ui location has been ported + # Then this will become /ui + location /ui { + proxy_pass http://ui.fake/; + + etag on; + expires 1y; + add_header Cache-Control $cache_control; + + gzip on; + gzip_types + application/javascript + application/json + application/manifest+json + application/wasm + application/x-javascript + application/x-web-app-manifest+json + image/* + text/css + text/javascript; + } + + location /auth { + internal; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Server $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_pass_request_body off; + proxy_set_header Content-Length ""; + proxy_pass http://127.0.0.1:8001/api/auth/; + } + + location /anon_auth { + internal; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Server $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_pass_request_body off; + proxy_set_header Content-Length ""; + proxy_pass http://127.0.0.1:8001/api/anon_auth/; + } + + location /grafana { + auth_request /anon_auth; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Server $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-WEBAUTH-USER "admin"; + rewrite ^/grafana/(.*) /$1 break; + proxy_pass http://127.0.0.1:3000; + + etag on; + expires 1y; + add_header Cache-Control $cache_control; + + gzip_proxied any; + } + + location /influx { + limit_except GET { deny all; } + auth_request /anon_auth; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Server $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_pass http://127.0.0.1:8086/query; + + gzip_proxied any; + } + + location /api/conf { + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Server $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_pass http://127.0.0.1:8004/conf; + } + + location /api/action { + auth_request /auth; + + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Server $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_pass http://127.0.0.1:8004/action; + + gzip on; + gzip_types application/json; + } + + location /api/task { + proxy_set_header Host $http_host; + auth_request /auth; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Server $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_pass http://127.0.0.1:8004/task; + + gzip on; + gzip_types application/json; + } + + location /api { + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Server $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_pass http://127.0.0.1:8001/api; + + gzip on; + gzip_types application/json; + } + + location /messaging { + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Server $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_http_version 1.1; + proxy_set_header Connection ''; + proxy_pass http://127.0.0.1:8890; + } + + location ~ /mailbox/(.+)$ { + if ($ssl_client_verify != SUCCESS) { + return 401; + } + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + sendfile_max_chunk 1m; + + alias /var/spool/iml/mailbox/$1; + } + + location /mailbox { + if ($ssl_client_verify != SUCCESS) { + return 401; + } + + client_max_body_size 0m; + + proxy_set_header X-SSL-Client-On $ssl_client_verify; + proxy_set_header X-SSL-Client-Name $ssl_client_s_dn_cn; + proxy_set_header X-SSL-Client-Serial $ssl_client_serial; + + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Server $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_pass http://127.0.0.1:8891/mailbox; + } + + location /agent/register { + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Server $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_pass http://127.0.0.1:8002/agent/register; + } + + location /agent/setup { + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Server $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_pass http://127.0.0.1:8002/agent/setup; + } + + location /agent/reregister { + if ($ssl_client_verify != SUCCESS) { + return 401; + } + + proxy_set_header X-SSL-Client-On $ssl_client_verify; + proxy_set_header X-SSL-Client-Name $ssl_client_s_dn_cn; + proxy_set_header X-SSL-Client-Serial $ssl_client_serial; + + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Server $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_pass http://127.0.0.1:8002/agent/reregister; + } + + location /agent/message { + client_body_buffer_size 1m; + client_max_body_size 8m; + + if ($ssl_client_verify != SUCCESS) { + return 401; + } + + proxy_set_header X-SSL-Client-On $ssl_client_verify; + proxy_set_header X-SSL-Client-Name $ssl_client_s_dn_cn; + proxy_set_header X-SSL-Client-Serial $ssl_client_serial; + + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Server $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_pass http://127.0.0.1:8002/agent/message; + } + + location /agent2/message { + client_body_buffer_size 1m; + client_max_body_size 8m; + + if ($ssl_client_verify != SUCCESS) { + return 401; + } + + proxy_set_header X-SSL-Client-On $ssl_client_verify; + proxy_set_header X-SSL-Client-Name $ssl_client_s_dn_cn; + proxy_set_header X-SSL-Client-Serial $ssl_client_serial; + + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Server $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_pass http://127.0.0.1:8003/message; + } + + location /agent/copytool_event { + if ($ssl_client_verify != SUCCESS) { + return 401; + } + + proxy_set_header X-SSL-Client-On $ssl_client_verify; + proxy_set_header X-SSL-Client-Name $ssl_client_s_dn_cn; + proxy_set_header X-SSL-Client-Serial $ssl_client_serial; + + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Server $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_pass http://127.0.0.1:8002/agent/copytool_event; + } + + location /repo/ { + if ($ssl_client_verify != SUCCESS) { + return 401; + } + + proxy_set_header X-SSL-Client-On $ssl_client_verify; + proxy_set_header X-SSL-Client-Name $ssl_client_s_dn_cn; + + autoindex on; + alias /var/lib/chroma/repo/; + } + + location /client/ { + autoindex on; + alias /var/lib/chroma/repo/lustre-client/; + } + + location /iml_has_package_updates { + if ($ssl_client_verify != SUCCESS) { + return 401; + } + + proxy_set_header X-SSL-Client-On $ssl_client_verify; + proxy_set_header X-SSL-Client-Name $ssl_client_s_dn_cn; + proxy_set_header X-SSL-Client-Serial $ssl_client_serial; + + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Server $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Http-Host $http_host; + proxy_pass http://unix:/var/run/iml-update-handler.sock; + } + + +} + +# We should be able to use `alias` / `root` with `try_files` +# However, due to https://trac.nginx.org/nginx/ticket/97 +# We need to do it this way. +upstream ui.fake { + server 127.0.0.1; +} + +server { + server_name ui.fake; + root /usr/share/iml-manager/rust-iml-gui; + index index.html; + + types { + application/javascript js; + application/json json map; + application/manifest+json webmanifest; + application/wasm wasm; + application/x-redhat-package-manager rpm; + application/x-x509-ca-cert der pem crt; + application/zip zip; + font/woff woff; + font/woff2 woff2; + image/gif gif; + image/jpeg jpeg jpg; + image/png png; + image/svg+xml svg; + image/x-icon ico; + text/css css; + text/html html htm; + text/plain txt; + text/xml xml rss; + } + + location / { + try_files $uri $uri/ /index.html; + } +} diff --git a/iml-sfa.service b/iml-sfa.service index 8f11149752..de74f6be76 100644 --- a/iml-sfa.service +++ b/iml-sfa.service @@ -10,6 +10,7 @@ Requires=iml-settings-populator.service Type=simple Environment=RUST_LOG=info EnvironmentFile=/var/lib/chroma/iml-settings.conf +EnvironmentFile=-/var/lib/chroma/overrides.conf ExecStart=/bin/iml-sfa Restart=on-failure RestartSec=2 diff --git a/nginx/nginx-dropin-iml.conf b/nginx/nginx-dropin-iml.conf new file mode 100644 index 0000000000..60fa11b8c7 --- /dev/null +++ b/nginx/nginx-dropin-iml.conf @@ -0,0 +1,4 @@ +[Service] +EnvironmentFile=/var/lib/chroma/iml-settings.conf +EnvironmentFile=-/var/lib/chroma/overrides.conf +ExecStartPre=/usr/bin/iml-config nginx generate-config --path /usr/share/chroma-manager/chroma-manager.conf.template --output /etc/nginx/conf.d/chroma-manager.conf \ No newline at end of file diff --git a/python-iml-manager.spec b/python-iml-manager.spec index 6432853015..140e50fbff 100644 --- a/python-iml-manager.spec +++ b/python-iml-manager.spec @@ -90,6 +90,7 @@ Requires: rust-iml-warp-drive >= 0.3.0 Requires: rust-iml-device >= 0.3.0 Requires: rust-iml-ntp >= 0.3.0 Requires: rust-iml-sfa >= 0.3.0 +Requires: rust-iml-config-cli >= 0.3.0 # Other Repos Requires: influxdb Requires: grafana @@ -185,6 +186,9 @@ mv $RPM_BUILD_ROOT%{manager_root}/grafana/dashboards/iml-dashboards.yaml $RPM_BU mv $RPM_BUILD_ROOT%{manager_root}/grafana/datasources/influxdb-iml-datasource.yml $RPM_BUILD_ROOT%{_sysconfdir}/grafana/provisioning/datasources mkdir -p $RPM_BUILD_ROOT%{_unitdir}/grafana-server.service.d/ mv $RPM_BUILD_ROOT%{manager_root}/grafana/dropin-iml.conf $RPM_BUILD_ROOT%{_unitdir}/grafana-server.service.d/90-iml.conf +cp -r nginx $RPM_BUILD_ROOT%{manager_root} +mkdir -p $RPM_BUILD_ROOT%{_unitdir}/nginx.service.d/ +mv $RPM_BUILD_ROOT%{manager_root}/nginx/nginx-dropin-iml.conf $RPM_BUILD_ROOT%{_unitdir}/nginx.service.d/90-nginx-dropin-iml.conf mkdir -p $RPM_BUILD_ROOT%{_unitdir}/rabbitmq-server.service.d mv rabbitmq-server-dropin.conf $RPM_BUILD_ROOT%{_unitdir}/rabbitmq-server.service.d/90-rabbitmq-server-dropin.conf cp iml-manager-redirect.conf $RPM_BUILD_ROOT%{_sysconfdir}/nginx/default.d/iml-manager-redirect.conf @@ -297,6 +301,7 @@ fi %{_sysconfdir}/grafana/grafana-iml.ini %{_unitdir}/grafana-server.service.d/90-iml.conf %{_unitdir}/rabbitmq-server.service.d/90-rabbitmq-server-dropin.conf +%{_unitdir}/nginx.service.d/90-nginx-dropin-iml.conf %attr(0755,root,root)%{_mandir}/man1/chroma-config.1.gz %attr(0644,root,root)%{_sysconfdir}/logrotate.d/chroma-manager %attr(0644,root,grafana)%{_sysconfdir}/grafana/provisioning/dashboards/iml-dashboards.yaml diff --git a/rust-iml.spec b/rust-iml.spec index 69bd028893..37dcf2c799 100644 --- a/rust-iml.spec +++ b/rust-iml.spec @@ -28,6 +28,7 @@ ExclusiveArch: x86_64 %install mkdir -p %{buildroot}%{_bindir} cp iml %{buildroot}%{_bindir} +cp iml-config %{buildroot}%{_bindir} cp iml-agent %{buildroot}%{_bindir} cp iml-agent-daemon %{buildroot}%{_bindir} cp iml-api %{buildroot}%{_bindir} @@ -73,6 +74,17 @@ Group: System Environment/Libraries %files cli %{_bindir}/iml +%package config-cli +Summary: IML manager Config CLI +License: MIT +Group: System Environment/Libraries + +%description config-cli +%{summary} + +%files config-cli +%{_bindir}/iml-config + %package agent Summary: IML Agent Daemon and CLI License: MIT diff --git a/tests/framework/services/runner.sh.in b/tests/framework/services/runner.sh.in index 33487a47c6..cda7957fe6 100755 --- a/tests/framework/services/runner.sh.in +++ b/tests/framework/services/runner.sh.in @@ -3,7 +3,7 @@ yum install -y epel-release yum clean all yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm -yum install -y git python-virtualenv python-setuptools python-devel gcc make graphviz-devel postgresql96-server postgresql96-devel rabbitmq-server telnet python-ethtool erlang-inets patch gcc-c++ systemd-devel python-pip curl libcurl-devel nss +yum install -y git python-virtualenv python-setuptools python-devel gcc make graphviz-devel postgresql96-server postgresql96-devel rabbitmq-server telnet python-ethtool erlang-inets patch gcc-c++ systemd-devel python-pip curl libcurl-devel nss openssl-devel cargo systemctl enable rabbitmq-server export PATH=$PATH:/usr/lib/rabbitmq/bin/ @@ -68,11 +68,14 @@ cp iml-settings-populator.service iml-syslog.service /lib/systemd/system pip install -r requirements.txt pip install -r requirements.test echo -e "/^DEBUG =/s/= .*$/= True/\nwq" | ed settings.py -PYTHONPATH=. python -c 'from chroma_core.lib.service_config import ServiceConfig; ServiceConfig().set_nginx_config()' cp -r /integrated-manager-for-lustre /usr/share/chroma-manager mkdir /var/log/chroma cd /usr/share/chroma-manager python ./manage.py dev_setup + +export PQ_LIB_DIR=/usr/pgsql-9.6/lib +env $(python manage.py print-settings 2> /dev/null | xargs) cargo run --bin iml-config nginx generate-config --path /integrated-manager-for-lustre/chroma-manager.conf.template --output /etc/nginx/conf.d/chroma-manager.conf + PYTHONPATH=. nosetests tests/services/ --stop diff --git a/vagrant/scripts/install_iml_local.sh b/vagrant/scripts/install_iml_local.sh index ef616714d6..f88adb2c29 100644 --- a/vagrant/scripts/install_iml_local.sh +++ b/vagrant/scripts/install_iml_local.sh @@ -128,7 +128,7 @@ EOF rm -rf /tmp/{manager,agent}-rpms mkdir -p /tmp/{manager,agent}-rpms -cp /tmp/iml/_topdir/RPMS/rust-iml-{action-runner,agent-comms,api,cli,mailbox,ntp,ostpool,postoffice,sfa,stats,device,warp-drive}-*.rpm /tmp/manager-rpms/ +cp /tmp/iml/_topdir/RPMS/rust-iml-{action-runner,agent-comms,api,cli,config-cli,mailbox,ntp,ostpool,postoffice,sfa,stats,device,warp-drive}-*.rpm /tmp/manager-rpms/ cp /tmp/iml/_topdir/RPMS/python2-iml-manager-*.rpm /tmp/manager-rpms/ cp /tmp/iml/_topdir/RPMS/rust-iml-agent-[0-9]*.rpm /tmp/agent-rpms cp /tmp/iml/chroma_support.repo /etc/yum.repos.d/