example/example.rs
1//! # Пример CloudPub SDK
2//!
3//! Этот пример демонстрирует полный рабочий процесс использования CloudPub Rust SDK,
4//! включая настройку соединения, публикацию сервисов, управление и очистку.
5//!
6//! ## Запуск примера
7//!
8//! ```bash
9//! cargo run --example example
10//! ```
11//!
12//! ## Предварительные требования
13//!
14//! 1. Сервер CloudPub должен быть запущен и доступен
15//! 2. Действительные учетные данные (email и пароль)
16//! 3. Локальные сервисы для публикации (пример использует localhost порты)
17
18use anyhow::Result;
19use cloudpub_sdk::protocol::{Auth, Endpoint, Protocol};
20use cloudpub_sdk::Connection;
21use std::io;
22use std::path::Path;
23
24#[tokio::main]
25async fn main() -> Result<()> {
26 // ====================================================================
27 // ШАГ 1: УСТАНОВЛЕНИЕ СОЕДИНЕНИЯ
28 // ====================================================================
29 println!("1. Подключение к серверу");
30
31 // Создание соединения с использованием паттерна билдера
32 // Билдер позволяет настроить различные параметры соединения
33 let mut conn = Connection::builder()
34 // Указать путь к пользовательскому файлу конфигурации (опционально)
35 // Если не указан, используется системное расположение по умолчанию
36 .config_path(Path::new("/tmp/cloudpub.toml"))
37 // Установить уровень логирования для отладки
38 // Варианты: "trace", "debug", "info", "warn", "error"
39 .log_level("info")
40 // Включить подробный вывод в stderr для отладки
41 // Полезно при разработке, отключите в продакшене
42 .verbose(true)
43 // Предоставить учетные данные для аутентификации
44 // Вы также можете использовать .token() для аутентификации на основе токена
45 .credentials("admin@example.com", "test")
46 // Установить таймаут для операций (в секундах)
47 // Применяется ко всем асинхронным операциям
48 .timeout_secs(3)
49 // Построить и установить соединение
50 // Произойдет аутентификация и ожидание готовности соединения
51 .build()
52 .await?;
53
54 // ====================================================================
55 // ШАГ 2: ПУБЛИКАЦИЯ HTTP СЕРВИСА
56 // ====================================================================
57 println!("2. Публикация нового HTTP сервиса...");
58
59 // Публикация локального HTTP сервиса для доступа через CloudPub
60 let endpoint = conn
61 .publish(
62 Protocol::Http, // Тип протокола
63 "localhost:8080".to_string(), // Локальный адрес для публикации
64 Some("Тестовый HTTP сервис".to_string()), // Человекочитаемое имя сервиса
65 Some(Auth::None), // Метод аутентификации для доступа к сервису
66 None, // Без ограничений ACL
67 None, // Без пользовательских заголовков
68 None, // Без правил фильтрации
69 )
70 .await?;
71
72 // Endpoint содержит информацию об опубликованном сервисе
73 // as_url() возвращает публичный URL, по которому доступен сервис
74 println!(" Сервис опубликован: {}", endpoint.as_url());
75
76 // ====================================================================
77 // ШАГ 3: ПУБЛИКАЦИЯ TCP СЕРВИСА
78 // ====================================================================
79 println!("3. Публикация нового TCP сервиса...");
80
81 // TCP сервисы полезны для публикации SSH, баз данных или пользовательских TCP протоколов
82 let endpoint = conn
83 .publish(
84 Protocol::Tcp, // TCP протокол
85 "localhost:22".to_string(), // Локальный SSH порт (пример)
86 Some("Тестовый TCP сервис".to_string()), // Имя сервиса
87 Some(Auth::None), // Аутентификация не требуется
88 None, // Без ограничений ACL
89 None, // Без пользовательских заголовков
90 None, // Без правил фильтрации
91 )
92 .await?;
93
94 println!(" Сервис опубликован: {}", endpoint.as_url());
95
96 // Сохранить GUID для последующих операций
97 // GUID уникально идентифицирует этот сервис
98 let service_guid = endpoint.guid.clone();
99
100 // ====================================================================
101 // ШАГ 4: СПИСОК ВСЕХ СЕРВИСОВ
102 // ====================================================================
103 println!("4. Список сервисов:");
104
105 // Получить все сервисы, зарегистрированные текущим пользователем
106 let services = conn.ls().await?;
107
108 // Отобразить каждый сервис с его GUID и URL
109 for service in &services {
110 println!(" {}: {}", service.guid, service.as_url());
111
112 // Сервисы также содержат дополнительные метаданные:
113 // - service.name: Опциональное человекочитаемое имя
114 // - service.status: Текущий статус (работает, остановлен и т.д.)
115 // - service.protocol: Тип протокола
116 // - service.auth: Метод аутентификации
117 }
118
119 // ====================================================================
120 // ШАГ 5: ЗАПУСК СЕРВИСА
121 // ====================================================================
122 println!("5. Запуск сервиса {}...", service_guid);
123
124 // Запустить ранее остановленный сервис
125 // Примечание: Сервисы обычно запускаются автоматически после публикации
126 conn.start(service_guid.clone()).await?;
127 println!(" - Сервис запущен");
128
129 // ====================================================================
130 // ШАГ 6: ПРОВЕРКА СТАТУСА СЕРВИСА
131 // ====================================================================
132 println!("6. Проверка статуса сервиса...");
133
134 // Получить список сервисов снова, чтобы увидеть обновленный статус
135 let services = conn.ls().await?;
136
137 // Найти наш конкретный сервис и отобразить его статус
138 if let Some(service) = services.iter().find(|s| s.guid == service_guid) {
139 println!(
140 " - Статус сервиса: {}",
141 service.status.as_ref().unwrap_or(&"Неизвестно".to_string())
142 );
143
144 // Поле статуса указывает состояние сервиса:
145 // - "running": Сервис активен и доступен
146 // - "stopped": Сервис зарегистрирован, но не доступен
147 // - "error": Сервис столкнулся с ошибкой
148 }
149
150 let mut buffer = String::new();
151 io::stdin()
152 .read_line(&mut buffer)
153 .expect("Не удалось прочитать строку");
154
155 // ====================================================================
156 // ШАГ 7: ОСТАНОВКА СЕРВИСА
157 // ====================================================================
158 println!("7. Остановка сервиса {}...", service_guid);
159
160 // Остановка делает сервис временно недоступным,
161 // но сохраняет его регистрацию
162 conn.stop(service_guid.clone()).await?;
163 println!(" - Сервис остановлен");
164
165 // ====================================================================
166 // ШАГ 8: ОТМЕНА ПУБЛИКАЦИИ СЕРВИСА
167 // ====================================================================
168 println!("8. Отмена регистрации сервиса {}...", service_guid);
169
170 // Отмена публикации удаляет регистрацию сервиса
171 // Сервис больше не будет доступен через CloudPub
172 conn.unpublish(service_guid.clone()).await?;
173 println!(" - Регистрация сервиса отменена");
174
175 // ====================================================================
176 // ШАГ 9: ПРОВЕРКА УДАЛЕНИЯ
177 // ====================================================================
178 println!("9. Финальный список сервисов...");
179
180 // Получить список сервисов для подтверждения удаления
181 let services = conn.ls().await?;
182 println!(" - Осталось {} сервис(ов)", services.len());
183
184 // ====================================================================
185 // ШАГ 10: ОЧИСТКА ВСЕХ СЕРВИСОВ
186 // ====================================================================
187 println!("10. Очистка всех сервисов...");
188
189 // Clean удаляет все сервисы, зарегистрированные текущим пользователем
190 // Используйте с осторожностью, так как это действие нельзя отменить
191 conn.clean().await?;
192 println!(" - Все сервисы удалены");
193
194 // Проверить, что все сервисы были удалены
195 let services = conn.ls().await?;
196 println!(" Финальное количество: {} сервис(ов)", services.len());
197
198 println!("Демонстрация успешно завершена!");
199
200 // ====================================================================
201 // ОЧИСТКА СОЕДИНЕНИЯ
202 // ====================================================================
203 // Соединение будет автоматически закрыто, когда `conn` выйдет из области видимости
204 // Реализация Drop обрабатывает:
205 // - Отправку сообщения Break для корректной остановки клиента
206 // - Отмену фоновых задач
207 // - Очистку ресурсов
208
209 Ok(())
210}