mirror of
https://github.com/NLnetLabs/krill.git
synced 2026-09-21 00:47:41 +02:00
387 lines
12 KiB
Rust
387 lines
12 KiB
Rust
extern crate krill_client;
|
|
extern crate krill_cms_proxy;
|
|
extern crate krill_commons;
|
|
extern crate krill_daemon;
|
|
extern crate krill_pubc;
|
|
|
|
use std::{thread, time};
|
|
use std::collections::HashSet;
|
|
use std::path::PathBuf;
|
|
use krill_client::KrillClient;
|
|
use krill_client::options::{
|
|
AddPublisher,
|
|
AddRfc8181Client,
|
|
Command,
|
|
Options,
|
|
PublishersCommand,
|
|
Rfc8181Command,
|
|
};
|
|
use krill_client::report::ReportFormat;
|
|
use krill_cms_proxy::rfc8183::RepositoryResponse;
|
|
use krill_commons::api::admin::{
|
|
Handle,
|
|
Token
|
|
};
|
|
use krill_commons::api::publication::ListReply;
|
|
use krill_commons::util::file::CurrentFile;
|
|
use krill_commons::util::file;
|
|
use krill_commons::util::httpclient;
|
|
use krill_commons::util::test;
|
|
use krill_pubc::{ApiResponse, Format};
|
|
use krill_pubc::apiclient;
|
|
use krill_pubc::cmsclient;
|
|
use krill_pubc::cmsclient::PubClient;
|
|
|
|
fn list(server_uri: &str, handle: &str, token: &str) -> apiclient::Options {
|
|
let conn = apiclient::Connection::build(server_uri, handle, token).unwrap();
|
|
let cmd = apiclient::Command::List;
|
|
let fmt = Format::Json;
|
|
|
|
apiclient::Options::new(conn, cmd, fmt)
|
|
}
|
|
|
|
fn sync(
|
|
server_uri: &str,
|
|
handle: &str,
|
|
token: &str,
|
|
syncdir: &PathBuf,
|
|
base_uri: &str
|
|
) -> apiclient::Options {
|
|
let conn = apiclient::Connection::build(server_uri, handle, token).unwrap();
|
|
let cmd = apiclient::Command::sync(syncdir.to_str().unwrap(), base_uri).unwrap();
|
|
let fmt = Format::Json;
|
|
|
|
apiclient::Options::new(conn, cmd, fmt)
|
|
}
|
|
|
|
fn execute_krillc_command(command: Command) {
|
|
let krillc_opts = Options::new(
|
|
test::https_uri("https://localhost:3000/"),
|
|
"secret",
|
|
ReportFormat::Default,
|
|
command
|
|
);
|
|
match KrillClient::test(krillc_opts) {
|
|
Ok(_res) => {}, // ok
|
|
Err(e) => {
|
|
panic!("{}", e)
|
|
}
|
|
}
|
|
}
|
|
|
|
fn add_publisher(handle: &str, base_uri: &str, token: &str) {
|
|
let command = Command::Publishers(PublishersCommand::Add(
|
|
AddPublisher {
|
|
handle: Handle::from(handle),
|
|
base_uri: test::rsync_uri(base_uri),
|
|
token: Token::from(token)
|
|
}
|
|
));
|
|
execute_krillc_command(command);
|
|
}
|
|
|
|
fn remove_publisher(handle: &str) {
|
|
let command = Command::Publishers(
|
|
PublishersCommand::Deactivate(handle.to_string())
|
|
);
|
|
|
|
execute_krillc_command(command);
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
fn rfc8181_client_init(handle: &str, state_dir: &PathBuf) {
|
|
let command = cmsclient::Command::init(handle);
|
|
rfc8181_client_process_command(command, &state_dir);
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
fn rfc8181_client_add(token: &str, state_dir: &PathBuf) {
|
|
let mut pr_path = state_dir.clone();
|
|
pr_path.push("request.xml");
|
|
|
|
let command = cmsclient::Command::publisher_request(pr_path.clone());
|
|
rfc8181_client_process_command(command, &state_dir);
|
|
|
|
let command = Command::Rfc8181(
|
|
Rfc8181Command::Add(
|
|
AddRfc8181Client { token: token.to_string(), xml: pr_path }
|
|
)
|
|
);
|
|
|
|
execute_krillc_command(command);
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
fn rfc8181_client_process_response(res_path: &PathBuf, state_dir: &PathBuf) {
|
|
let command = cmsclient::Command::repository_response(res_path.clone());
|
|
rfc8181_client_process_command(command, &state_dir);
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
fn rfc8181_client_list(state_dir: &PathBuf) -> ListReply {
|
|
let command = cmsclient::Command::list();
|
|
let api_response = rfc8181_client_process_command(command, &state_dir);
|
|
match api_response {
|
|
ApiResponse::Success => panic!("Expected list"),
|
|
ApiResponse::List(list) => list
|
|
}
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
fn rfc8181_client_sync(state_dir: &PathBuf, sync_dir: &PathBuf) {
|
|
let command = cmsclient::Command::sync(sync_dir.clone());
|
|
rfc8181_client_process_command(command, state_dir);
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
fn rfc8181_client_process_command(command: cmsclient::Command, state_dir: &PathBuf) -> ApiResponse {
|
|
let options = cmsclient::Options::new(state_dir.clone(), command, Format::None);
|
|
PubClient::execute(options).unwrap()
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
fn get_repository_response(handle: &str) -> RepositoryResponse {
|
|
let uri = format!("https://localhost:3000/api/v1/rfc8181/{}/response.xml", handle);
|
|
let content_type = "application/xml";
|
|
let token = Token::from("secret");
|
|
|
|
let xml = httpclient::get_text(
|
|
&uri, content_type, Some(&token)
|
|
).unwrap();
|
|
|
|
RepositoryResponse::decode(xml.as_bytes()).unwrap()
|
|
}
|
|
|
|
#[test]
|
|
fn client_publish() {
|
|
krill_daemon::test::test_with_krill_server(|d| {
|
|
|
|
let server_uri = "https://localhost:3000/";
|
|
let handle = "alice";
|
|
let token = "secret";
|
|
let base_rsync_uri_alice = "rsync://localhost/repo/alice/";
|
|
let base_rsync_uri_bob = "rsync://localhost/repo/bob/";
|
|
|
|
// XXX TODO: Find a better way to know the server is ready!
|
|
thread::sleep(time::Duration::from_millis(500));
|
|
|
|
// Add client "alice"
|
|
add_publisher(handle, base_rsync_uri_alice, token);
|
|
|
|
// Calls to api should require the correct token
|
|
{
|
|
let res = apiclient::execute(list(
|
|
server_uri,
|
|
handle,
|
|
"wrong token"
|
|
));
|
|
|
|
match res {
|
|
Err(apiclient::Error::HttpClientError
|
|
(httpclient::Error::Forbidden)) => {},
|
|
Err(e) => panic!("Expected forbidden, got: {}", e),
|
|
_ => panic!("Expected forbidden")
|
|
}
|
|
}
|
|
|
|
// List files at server, expect no files
|
|
{
|
|
let list = apiclient::execute(list(
|
|
server_uri,
|
|
handle,
|
|
token
|
|
)).unwrap();
|
|
|
|
match list {
|
|
ApiResponse::List(list) => {
|
|
assert_eq!(0, list.elements().len());
|
|
},
|
|
_ => panic!("Expected list")
|
|
}
|
|
}
|
|
|
|
|
|
// Create files on disk to sync
|
|
let sync_dir = test::create_sub_dir(&d);
|
|
let file_a = CurrentFile::new(
|
|
test::rsync_uri("rsync://localhost/repo/alice/a.txt"),
|
|
&test::as_bytes("a")
|
|
);
|
|
let file_b = CurrentFile::new(
|
|
test::rsync_uri("rsync://localhost/repo/alice/b.txt"),
|
|
&test::as_bytes("b")
|
|
);
|
|
let file_c = CurrentFile::new(
|
|
test::rsync_uri("rsync://localhost/repo/alice/c.txt"),
|
|
&test::as_bytes("c")
|
|
);
|
|
|
|
file::save_in_dir(&file_a.to_bytes(), &sync_dir, "a.txt").unwrap();
|
|
file::save_in_dir(&file_b.to_bytes(), &sync_dir, "b.txt").unwrap();
|
|
file::save_in_dir(&file_c.to_bytes(), &sync_dir, "c.txt").unwrap();
|
|
|
|
|
|
// Must refuse syncing files outside of publisher base dir
|
|
{
|
|
let api_res = apiclient::execute(sync(
|
|
server_uri,
|
|
handle,
|
|
token,
|
|
&sync_dir,
|
|
base_rsync_uri_bob
|
|
));
|
|
|
|
assert!(api_res.is_err())
|
|
}
|
|
|
|
|
|
// Sync files
|
|
{
|
|
let api_res = apiclient::execute(sync(
|
|
server_uri,
|
|
handle,
|
|
token,
|
|
&sync_dir,
|
|
base_rsync_uri_alice
|
|
)).unwrap();
|
|
|
|
assert_eq!(ApiResponse::Success, api_res);
|
|
}
|
|
|
|
// We should now see these files when we list
|
|
{
|
|
let list = apiclient::execute(list(
|
|
server_uri,
|
|
handle,
|
|
token
|
|
)).unwrap();
|
|
|
|
match list {
|
|
ApiResponse::List(list) => {
|
|
assert_eq!(3, list.elements().len());
|
|
|
|
let returned_set: HashSet<_> = list.elements().into_iter().collect();
|
|
|
|
let list_el_a = file_a.into_list_element();
|
|
let list_el_b = file_b.into_list_element();
|
|
let list_el_c = file_c.clone().into_list_element();
|
|
|
|
let expected_elements = vec![
|
|
&list_el_a,
|
|
&list_el_b,
|
|
&list_el_c
|
|
];
|
|
let expected_set: HashSet<_> = expected_elements.into_iter().collect();
|
|
assert_eq!(expected_set, returned_set);
|
|
},
|
|
_ => panic!("Expected list")
|
|
}
|
|
}
|
|
|
|
// XXX TODO We should also see these files in RRDP
|
|
|
|
|
|
// Now we should be able to delete it all again
|
|
file::delete_in_dir(&sync_dir, "a.txt").unwrap();
|
|
file::delete_in_dir(&sync_dir, "b.txt").unwrap();
|
|
|
|
// Sync files
|
|
{
|
|
let api_res = apiclient::execute(sync(
|
|
server_uri,
|
|
handle,
|
|
token,
|
|
&sync_dir,
|
|
base_rsync_uri_alice
|
|
)).unwrap();
|
|
|
|
assert_eq!(ApiResponse::Success, api_res);
|
|
}
|
|
|
|
// List files at server, expect 1 file (c.txt)
|
|
{
|
|
let list = apiclient::execute(list(
|
|
server_uri,
|
|
handle,
|
|
token
|
|
)).unwrap();
|
|
|
|
match list {
|
|
ApiResponse::List(list) => {
|
|
assert_eq!(1, list.elements().len());
|
|
|
|
let returned_set: HashSet<_> = list.elements().into_iter().collect();
|
|
|
|
let list_el_c = file_c.into_list_element();
|
|
|
|
let expected_elements = vec![&list_el_c];
|
|
let expected_set: HashSet<_> = expected_elements.into_iter().collect();
|
|
assert_eq!(expected_set, returned_set);
|
|
},
|
|
_ => panic!("Expected list")
|
|
}
|
|
}
|
|
|
|
// Remove alice
|
|
remove_publisher(handle);
|
|
|
|
// XXX TODO Must remove files when removing publisher
|
|
// Expect that c.txt is removed when looking at latest snapshot.
|
|
file::delete_in_dir(&sync_dir, "c.txt").unwrap();
|
|
|
|
// Now test with CMS proxy
|
|
|
|
let handle = "carol";
|
|
let token = "secret";
|
|
let base_rsync_uri = "rsync://localhost/repo/carol/";
|
|
|
|
// Add client "carol"
|
|
add_publisher(handle, base_rsync_uri, token);
|
|
|
|
// let state_dir = test::create_sub_dir(&d);
|
|
//
|
|
// // Add RFC8181 client for alice
|
|
// rfc8181_client_init(handle, &state_dir);
|
|
//
|
|
// rfc8181_client_add(token, &state_dir);
|
|
//
|
|
// // Get the server response.xml and add it to the client
|
|
// let response = get_repository_response(handle);
|
|
// let mut response_path = state_dir.clone();
|
|
// response_path.push("response.xml");
|
|
// response.save(&response_path).unwrap();
|
|
//
|
|
// rfc8181_client_process_response(&response_path, &state_dir);
|
|
//
|
|
// // List the files
|
|
// let list = rfc8181_client_list(&state_dir);
|
|
// assert_eq!(0, list.elements().len());
|
|
//
|
|
// // Create files on disk to sync
|
|
// let sync_dir = test::create_sub_dir(&d);
|
|
// let file_a = CurrentFile::new(
|
|
// test::rsync_uri("rsync://localhost/repo/alice/a.txt"),
|
|
// &test::as_bytes("a")
|
|
// );
|
|
// let file_b = CurrentFile::new(
|
|
// test::rsync_uri("rsync://localhost/repo/alice/b.txt"),
|
|
// &test::as_bytes("b")
|
|
// );
|
|
// let file_c = CurrentFile::new(
|
|
// test::rsync_uri("rsync://localhost/repo/alice/c.txt"),
|
|
// &test::as_bytes("c")
|
|
// );
|
|
//
|
|
// file::save_in_dir(&file_a.to_bytes(), &sync_dir, "a.txt").unwrap();
|
|
// file::save_in_dir(&file_b.to_bytes(), &sync_dir, "b.txt").unwrap();
|
|
// file::save_in_dir(&file_c.to_bytes(), &sync_dir, "c.txt").unwrap();
|
|
//
|
|
// // Sync
|
|
// rfc8181_client_sync(&state_dir, &sync_dir);
|
|
//
|
|
// // List the files
|
|
// let list = rfc8181_client_list(&state_dir);
|
|
// assert_eq!(3, list.elements().len());
|
|
});
|
|
|
|
} |