├── .cursor └── rules │ ├── cursor_rules.mdc │ ├── front-end.mdc │ ├── markdown-doc-site.mdc │ ├── self_improve.mdc │ └── tdd.mdc ├── .env ├── .env.dev ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── dependabot.yml └── workflows │ ├── changelog.yml │ ├── create-release-package.yml │ ├── dependency-review.yml │ ├── docker-publish-demo.yml │ ├── docker-publish.yml │ ├── pr-to-release-branch-on-tag.yml │ ├── test-client.yml │ ├── test-playbooks.yml │ └── test-server.yml ├── .gitignore ├── .gitmodules ├── .husky └── pre-commit ├── CHANGELOG.md ├── CONTRIBUTING.md ├── Dockerfile.koyeb ├── LICENSE ├── README.md ├── client ├── .dockerignore ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .prettierignore ├── .prettierrc ├── .prettierrc.js ├── Dockerfile ├── README.md ├── babel.config.js ├── config │ ├── config.ts │ ├── defaultSettings.ts │ ├── proxy.ts │ └── routes.ts ├── documentation │ ├── CLIENT_ARCHITECTURE_TARGET.md │ ├── CLIENT_IMPLEMENTATION_PLAN.md │ ├── client-components-detailed-changes.md │ ├── client-components-reorganization.md │ └── client-refactoring-plan.md ├── jsconfig.json ├── package-lock.json ├── package.json ├── production-server.js ├── public │ ├── avatars │ │ ├── squirrel.png │ │ └── squirrel.svg │ ├── favicon.ico │ ├── favicon.png │ ├── favicon.svg │ ├── images │ │ ├── home-dashboard.png │ │ ├── home-devices.png │ │ ├── home-services.png │ │ └── home-store.png │ ├── logo.svg │ ├── lotties │ │ ├── running_squirrel.lottie │ │ └── squirrel_find_nut.lottie │ ├── onboarding │ │ ├── acorn.png │ │ ├── thump.png │ │ ├── tree.png │ │ └── tree2.png │ ├── requestRecord.mock.js │ ├── safari-pinned-tab.svg │ ├── scripts │ │ └── loading.js │ ├── site.webmanifest │ └── squirrels │ │ ├── cleaned_smooth_fox.svg │ │ ├── happy-fox.svg │ │ └── optimized_running_fox.svg ├── scripts │ ├── README.md │ └── lint-check.js ├── src │ ├── access.ts │ ├── app.tsx │ ├── components │ │ ├── Alert │ │ │ └── AlertNotification.tsx │ │ ├── AnimatedInfoText.tsx │ │ ├── Charts │ │ │ ├── CustomRingProgress.tsx │ │ │ ├── TinyLineDeviceGraph.tsx │ │ │ ├── TinyRingProgressDeviceGraph.tsx │ │ │ └── TinyRingProgressDeviceIndicator.tsx │ │ ├── ComposeEditor │ │ │ ├── DockerComposeStackBuilder.tsx │ │ │ ├── DraggableCard.tsx │ │ │ ├── DroppableArea.tsx │ │ │ ├── FloatingButtonsBar.tsx │ │ │ ├── Menu │ │ │ │ ├── MenuElementIcons.tsx │ │ │ │ ├── MenuElements.ts │ │ │ │ ├── MenuTemplateElements.ts │ │ │ │ └── StackMenuIconsGrid.tsx │ │ │ ├── StackHandler.ts │ │ │ ├── StackIconSelector.tsx │ │ │ ├── StackMenu.tsx │ │ │ ├── StackPanel.tsx │ │ │ ├── ViewBuilder.tsx │ │ │ ├── ViewBuilderElements │ │ │ │ ├── ActionsIcons.tsx │ │ │ │ ├── CollapseContent.tsx │ │ │ │ ├── LabelUtils.tsx │ │ │ │ ├── RenderFields.tsx │ │ │ │ ├── SmartFields.tsx │ │ │ │ └── SubRowBuilder.tsx │ │ │ ├── types.ts │ │ │ └── utils │ │ │ │ ├── id.ts │ │ │ │ ├── random-names.ts │ │ │ │ └── variants.ts │ │ ├── ContainerComponents │ │ │ └── ContainerQuickAction │ │ │ │ ├── ContainerQuickActionDropDown.tsx │ │ │ │ └── ContainerQuickActionReference.tsx │ │ ├── DeviceComponents │ │ │ ├── CPULogo.tsx │ │ │ ├── DeviceInformation │ │ │ │ ├── DeviceInformationModal.tsx │ │ │ │ ├── DeviceManagementModal.tsx │ │ │ │ └── components │ │ │ │ │ ├── CPUTab.tsx │ │ │ │ │ ├── FilesystemsTab.tsx │ │ │ │ │ ├── GraphicsTab.tsx │ │ │ │ │ ├── MemoryTab.tsx │ │ │ │ │ ├── NetworkInterfacesTab.tsx │ │ │ │ │ ├── OSTab.tsx │ │ │ │ │ ├── SummaryTab.tsx │ │ │ │ │ ├── SystemInformationView.tsx │ │ │ │ │ ├── SystemTab.tsx │ │ │ │ │ ├── USBTab.tsx │ │ │ │ │ └── WifiTab.tsx │ │ │ ├── DeviceLogos.tsx │ │ │ ├── DeviceQuickAction │ │ │ │ ├── DeviceQuickActionDropDown.tsx │ │ │ │ └── DeviceQuickActionReference.tsx │ │ │ ├── DeviceStatusTag.tsx │ │ │ ├── OSSoftwaresVersions │ │ │ │ ├── OsSoftwareVersions.tsx │ │ │ │ ├── SoftwareIcon.tsx │ │ │ │ └── SoftwareIcons.tsx │ │ │ ├── OsLogo │ │ │ │ ├── OsLogo.tsx │ │ │ │ └── img │ │ │ │ │ ├── 128_alma_darkblue.png │ │ │ │ │ ├── 128_alma_green.png │ │ │ │ │ ├── 128_alma_lightblue.png │ │ │ │ │ ├── 128_alma_purple.png │ │ │ │ │ ├── 128_alma_red.png │ │ │ │ │ ├── 128_alma_yellow.png │ │ │ │ │ ├── 128_alpine.png │ │ │ │ │ ├── 128_antix.png │ │ │ │ │ ├── 128_antix_black.png │ │ │ │ │ ├── 128_apple-dark.png │ │ │ │ │ ├── 128_arch.png │ │ │ │ │ ├── 128_arco.png │ │ │ │ │ ├── 128_artix.png │ │ │ │ │ ├── 128_bluestar.png │ │ │ │ │ ├── 128_bodhi.png │ │ │ │ │ ├── 128_bodhi_black.png │ │ │ │ │ ├── 128_bunsenlabs.png │ │ │ │ │ ├── 128_bunsenlabs_black.png │ │ │ │ │ ├── 128_bunsenlabs_yellow.png │ │ │ │ │ ├── 128_bunsenlabs_yellow_black.png │ │ │ │ │ ├── 128_centos_blue.png │ │ │ │ │ ├── 128_centos_green.png │ │ │ │ │ ├── 128_centos_orange.png │ │ │ │ │ ├── 128_centos_purple.png │ │ │ │ │ ├── 128_clear.png │ │ │ │ │ ├── 128_clear_black.png │ │ │ │ │ ├── 128_debian.png │ │ │ │ │ ├── 128_deepin.png │ │ │ │ │ ├── 128_elementary.png │ │ │ │ │ ├── 128_endeavour.png │ │ │ │ │ ├── 128_endeavour_black.png │ │ │ │ │ ├── 128_endeavour_blue.png │ │ │ │ │ ├── 128_endeavour_blue_black.png │ │ │ │ │ ├── 128_endeavour_red.png │ │ │ │ │ ├── 128_endeavour_red_black.png │ │ │ │ │ ├── 128_endless.png │ │ │ │ │ ├── 128_endless_black.png │ │ │ │ │ ├── 128_fedora_newlogo.png │ │ │ │ │ ├── 128_fedora_newlogo_oldcolor.png │ │ │ │ │ ├── 128_fedora_oldlogo.png │ │ │ │ │ ├── 128_fedora_oldlogo_newcolor.png │ │ │ │ │ ├── 128_feren.png │ │ │ │ │ ├── 128_feren_black.png │ │ │ │ │ ├── 128_garuda_blue.png │ │ │ │ │ ├── 128_garuda_orange.png │ │ │ │ │ ├── 128_garuda_orange_light.png │ │ │ │ │ ├── 128_garuda_purple.png │ │ │ │ │ ├── 128_generic.png │ │ │ │ │ ├── 128_gentoo.png │ │ │ │ │ ├── 128_kali.png │ │ │ │ │ ├── 128_kali_black.png │ │ │ │ │ ├── 128_kaos.png │ │ │ │ │ ├── 128_knoppix.png │ │ │ │ │ ├── 128_kubuntu.png │ │ │ │ │ ├── 128_linux.png │ │ │ │ │ ├── 128_lite.png │ │ │ │ │ ├── 128_lite_black.png │ │ │ │ │ ├── 128_lubuntu.png │ │ │ │ │ ├── 128_mabox_v01.png │ │ │ │ │ ├── 128_mabox_v02.png │ │ │ │ │ ├── 128_mabox_v03.png │ │ │ │ │ ├── 128_mageia.png │ │ │ │ │ ├── 128_manjaro.png │ │ │ │ │ ├── 128_mint.png │ │ │ │ │ ├── 128_mx.png │ │ │ │ │ ├── 128_mx_black.png │ │ │ │ │ ├── 128_neon.png │ │ │ │ │ ├── 128_netrunner.png │ │ │ │ │ ├── 128_nixos.png │ │ │ │ │ ├── 128_openmandriva.png │ │ │ │ │ ├── 128_parrot.png │ │ │ │ │ ├── 128_parrot_black.png │ │ │ │ │ ├── 128_pclinuxos.png │ │ │ │ │ ├── 128_peppermint.png │ │ │ │ │ ├── 128_pop.png │ │ │ │ │ ├── 128_pop_black.png │ │ │ │ │ ├── 128_puppy_blue.png │ │ │ │ │ ├── 128_puppy_brown.png │ │ │ │ │ ├── 128_q4os_blue.png │ │ │ │ │ ├── 128_q4os_lightblue.png │ │ │ │ │ ├── 128_q4os_orange.png │ │ │ │ │ ├── 128_qubes.png │ │ │ │ │ ├── 128_raspios.png │ │ │ │ │ ├── 128_raspios_alt.png │ │ │ │ │ ├── 128_rebornos.png │ │ │ │ │ ├── 128_redhat.png │ │ │ │ │ ├── 128_redhat_black.png │ │ │ │ │ ├── 128_rosa.png │ │ │ │ │ ├── 128_septor.png │ │ │ │ │ ├── 128_slackware.png │ │ │ │ │ ├── 128_solus.png │ │ │ │ │ ├── 128_suse.png │ │ │ │ │ ├── 128_tails.png │ │ │ │ │ ├── 128_tinycore.png │ │ │ │ │ ├── 128_ubuntu.png │ │ │ │ │ ├── 128_ubuntu_cinnamon.png │ │ │ │ │ ├── 128_ubuntu_dde.png │ │ │ │ │ ├── 128_ubuntu_mate.png │ │ │ │ │ ├── 128_ubuntu_unity_newcolor.png │ │ │ │ │ ├── 128_ubuntu_unity_oldcolor.png │ │ │ │ │ ├── 128_void.png │ │ │ │ │ ├── 128_windows.png │ │ │ │ │ ├── 128_xubuntu.png │ │ │ │ │ ├── 128_zorin.png │ │ │ │ │ ├── freebsd.jpeg │ │ │ │ │ ├── openbsd_logo_icon_248311.png │ │ │ │ │ └── reactos.png │ │ │ └── SFTPDrawer │ │ │ │ ├── Actions │ │ │ │ ├── DownloadModal.tsx │ │ │ │ ├── MkdirModal.tsx │ │ │ │ ├── RenameModal.tsx │ │ │ │ └── UpdateModeModal.tsx │ │ │ │ ├── SFTPDrawer.tsx │ │ │ │ ├── SFTPDropdownMenu.tsx │ │ │ │ └── utils.ts │ │ ├── DeviceConfiguration │ │ │ ├── AdvancedSwitch.tsx │ │ │ ├── AgentInstallMethod.tsx │ │ │ ├── CheckDeviceConnection.tsx │ │ │ ├── DockerConfigurationFormElements.tsx │ │ │ ├── ProxmoxConfigurationFormElements.tsx │ │ │ ├── SSHConnectionFormElements.tsx │ │ │ ├── capability │ │ │ │ └── CapabilityCard.tsx │ │ │ ├── diagnostic │ │ │ │ ├── ExistingDeviceAdvancedDiagnostic.tsx │ │ │ │ ├── ExistingDeviceConnectionTest.tsx │ │ │ │ └── SystemInformationDebug.tsx │ │ │ ├── docker │ │ │ │ ├── DockerAdvancedConnectionCard.tsx │ │ │ │ ├── DockerEngineHostCard.tsx │ │ │ │ ├── DockerWatchCard.tsx │ │ │ │ └── DockerWatcherCronsCard.tsx │ │ │ ├── proxmox │ │ │ │ ├── ProxmoxConnectionCard.tsx │ │ │ │ └── ProxmoxWatcherCronsCard.tsx │ │ │ └── ssh │ │ │ │ ├── AuthenticationCard.tsx │ │ │ │ ├── HostCard.tsx │ │ │ │ └── SuperUserCard.tsx │ │ ├── Footer │ │ │ └── index.tsx │ │ ├── FullScreenLoader │ │ │ └── FullScreenLoader.tsx │ │ ├── HeaderComponents │ │ │ ├── AvatarDropdown.tsx │ │ │ ├── DevicesHeaderWidget.tsx │ │ │ ├── DocumentationWidget.tsx │ │ │ ├── HeaderDropDown.tsx │ │ │ ├── HealthWidget.tsx │ │ │ ├── NotificationsWidget.tsx │ │ │ ├── PlaybookExecutionWidget.less │ │ │ ├── PlaybookExecutionWidget.tsx │ │ │ └── UpdateAvailableWidget.tsx │ │ ├── Icons │ │ │ └── CustomIcons.tsx │ │ ├── Indicators │ │ │ └── CountDisplay.tsx │ │ ├── Layout │ │ │ ├── ModalStyledTabs.tsx │ │ │ └── StyledTabContainer.tsx │ │ ├── LiveLogs │ │ │ ├── LiveLogs.tsx │ │ │ └── LiveLogsToolbar.tsx │ │ ├── Message │ │ │ └── DynamicMessage.tsx │ │ ├── NewDeviceModal │ │ │ ├── AnimationPlayer.tsx │ │ │ ├── NewDeviceModal.tsx │ │ │ ├── StepFormCard.tsx │ │ │ ├── SummaryCard.tsx │ │ │ └── SwitchConnexionMethod.tsx │ │ ├── NoDevice │ │ │ ├── CarouselNoDevice.tsx │ │ │ ├── CarouselWithBlur.less │ │ │ └── NoDeviceModal.tsx │ │ ├── PlaybookExecutionModal │ │ │ ├── PlaybookExecutionHandler.ts │ │ │ ├── PlaybookExecutionTerminalModal.tsx │ │ │ ├── TaskStatusTimeline.tsx │ │ │ └── index.tsx │ │ ├── PlaybookSelection │ │ │ ├── ExtraVarIcon.tsx │ │ │ ├── ExtraVarView.tsx │ │ │ └── PlaybookSelectionModal.tsx │ │ ├── RegistryComponents │ │ │ └── RegistryLogo.tsx │ │ ├── Shared │ │ │ └── InfoLinkWidget.tsx │ │ ├── Template │ │ │ ├── CardHeader.tsx │ │ │ └── Title.tsx │ │ └── Terminal │ │ │ ├── RemoteSystemInformationTerminal.tsx │ │ │ └── TerminalCore.tsx │ ├── global.less │ ├── global.tsx │ ├── locales │ │ └── en-US.ts │ ├── manifest.json │ ├── pages │ │ ├── 404.tsx │ │ ├── Admin │ │ │ ├── Inventory │ │ │ │ ├── InventoryColumns.tsx │ │ │ │ ├── components │ │ │ │ │ ├── ConfigurationModal.tsx │ │ │ │ │ └── tabs │ │ │ │ │ │ ├── AgentConfigurationTab.tsx │ │ │ │ │ │ ├── ContainersConfigurationTab.tsx │ │ │ │ │ │ ├── DiagnosticTab.tsx │ │ │ │ │ │ ├── SSHConfigurationFormTab.tsx │ │ │ │ │ │ ├── SystemInformationConfigurationTab.tsx │ │ │ │ │ │ └── containers │ │ │ │ │ │ ├── DockerConfigurationForm.tsx │ │ │ │ │ │ └── ProxmoxConfigurationForm.tsx │ │ │ │ └── index.tsx │ │ │ ├── Logs │ │ │ │ ├── ServerLogsColums.tsx │ │ │ │ ├── TaskLogsColumns.tsx │ │ │ │ ├── TaskLogsTerminalModal.tsx │ │ │ │ └── index.tsx │ │ │ └── Settings │ │ │ │ ├── Settings.tsx │ │ │ │ └── components │ │ │ │ ├── AdvancedSettings.tsx │ │ │ │ ├── AuthenticationSettings.tsx │ │ │ │ ├── ContainerStacksSettings.tsx │ │ │ │ ├── GeneralSettings.tsx │ │ │ │ ├── Information.tsx │ │ │ │ ├── MCPSettings.tsx │ │ │ │ ├── PlaybooksSettings.tsx │ │ │ │ ├── RegistrySettings.tsx │ │ │ │ └── subcomponents │ │ │ │ ├── AnsibleConfiguration.tsx │ │ │ │ ├── ContainerStacksGitRepositoryModal.tsx │ │ │ │ ├── CustomVaultModal.tsx │ │ │ │ ├── PlaybooksGitRepositoryModal.tsx │ │ │ │ ├── PlaybooksLocalRepositoryModal.tsx │ │ │ │ ├── RegistryModal.tsx │ │ │ │ └── forms │ │ │ │ ├── CustomVault.tsx │ │ │ │ ├── DirectoryExclusionForm.tsx │ │ │ │ ├── FileMatchesForm.tsx │ │ │ │ └── GitForm.tsx │ │ ├── Automations │ │ │ ├── Automations.tsx │ │ │ ├── AutomationsColumns.tsx │ │ │ ├── CronsColumns.tsx │ │ │ └── components │ │ │ │ ├── AutomationQuickAction.tsx │ │ │ │ └── Drawer │ │ │ │ ├── AutomationActionInnerCard.tsx │ │ │ │ ├── AutomationActionTitle.tsx │ │ │ │ ├── AutomationEditionDrawer.tsx │ │ │ │ ├── AutomationTriggerInnerCard.tsx │ │ │ │ ├── DockerActionSubForm.tsx │ │ │ │ ├── DockerVolumeActionSubForm.tsx │ │ │ │ ├── PlaybookActionSubForm.tsx │ │ │ │ ├── templates-data │ │ │ │ └── TemplateList.tsx │ │ │ │ └── utils.ts │ │ ├── ComposeEditor │ │ │ └── index.tsx │ │ ├── Containers │ │ │ ├── components │ │ │ │ ├── Containers.tsx │ │ │ │ ├── Images.tsx │ │ │ │ ├── Networks.tsx │ │ │ │ ├── Stacks.tsx │ │ │ │ ├── Templates.tsx │ │ │ │ ├── Volumes.tsx │ │ │ │ ├── containers │ │ │ │ │ ├── ContainerAvatar.tsx │ │ │ │ │ ├── ContainerDetailsModal.tsx │ │ │ │ │ ├── ContainerMetas.tsx │ │ │ │ │ ├── ContainerStatProgress.tsx │ │ │ │ │ ├── ContainerStatsDetail.tsx │ │ │ │ │ ├── EditContainerNameModal.tsx │ │ │ │ │ ├── InfoToolTipCard.tsx │ │ │ │ │ ├── StatusTag.tsx │ │ │ │ │ ├── UpdateAvailableTag.tsx │ │ │ │ │ └── container-details │ │ │ │ │ │ ├── ContainerTypeIcon.tsx │ │ │ │ │ │ ├── DockerContainerDetails.tsx │ │ │ │ │ │ └── ProxmoxContainerDetails.tsx │ │ │ │ └── sub-components │ │ │ │ │ ├── ContainerBackUpVolumeInProgressModal.tsx │ │ │ │ │ ├── ContainerBackUpVolumeModal.tsx │ │ │ │ │ ├── CreateNetworkModal.tsx │ │ │ │ │ ├── CreateVolumeModal.tsx │ │ │ │ │ ├── DeployCustomStackModal.tsx │ │ │ │ │ ├── DeployModal.tsx │ │ │ │ │ ├── DockerOpsModal.tsx │ │ │ │ │ └── deploy-configuration-forms │ │ │ │ │ ├── NetworkTypes.tsx │ │ │ │ │ ├── ProCardEnvironmentConfiguration.tsx │ │ │ │ │ ├── ProCardExtrasConfiguration.tsx │ │ │ │ │ ├── ProCardGeneralConfiguration.tsx │ │ │ │ │ ├── ProCardLabelsConfiguration.tsx │ │ │ │ │ ├── ProCardPortsConfiguration.tsx │ │ │ │ │ └── ProCardVolumesConfiguration.tsx │ │ │ ├── index.tsx │ │ │ └── logs │ │ │ │ └── Logs.tsx │ │ ├── Dashboard │ │ │ ├── Analysis.less │ │ │ ├── ChartComponents │ │ │ │ ├── ChartCard.less │ │ │ │ ├── ChartCard.tsx │ │ │ │ ├── Field.less │ │ │ │ ├── Field.tsx │ │ │ │ ├── MiniProgress.less │ │ │ │ ├── MiniProgress.tsx │ │ │ │ ├── Trend.less │ │ │ │ └── Trend.tsx │ │ │ ├── Components │ │ │ │ ├── AvailabilityCard.tsx │ │ │ │ ├── CombinedPowerCard.tsx │ │ │ │ ├── ContainersCard.tsx │ │ │ │ ├── DashboardTop.tsx │ │ │ │ ├── MainChartCard.tsx │ │ │ │ └── SystemPerformanceCard.tsx │ │ │ └── index.tsx │ │ ├── Devices │ │ │ ├── DeviceSSHTerminal.tsx │ │ │ ├── Devices.less │ │ │ ├── components │ │ │ │ └── ListComponent.tsx │ │ │ └── index.tsx │ │ ├── Playbooks │ │ │ ├── components │ │ │ │ ├── CreateFileInRepositoryModalForm.tsx │ │ │ │ ├── CreateNewVarForm.tsx │ │ │ │ ├── DirectoryTreeView.tsx │ │ │ │ ├── ExtraVarsViewEditor.tsx │ │ │ │ ├── FloatingButtonsBar.tsx │ │ │ │ ├── GalaxyStoreModal.tsx │ │ │ │ ├── NewFileDrawerForm.tsx │ │ │ │ ├── PlaybookDropdownMenu.tsx │ │ │ │ └── TreeComponent.tsx │ │ │ └── index.tsx │ │ ├── Plugins │ │ │ ├── [pluginId].tsx │ │ │ ├── components │ │ │ │ ├── InstalledPluginsList.tsx │ │ │ │ ├── PluginDetailModal.tsx │ │ │ │ ├── PluginStoreTab.tsx │ │ │ │ └── RepositoryManagementModal.tsx │ │ │ └── index.tsx │ │ └── User │ │ │ ├── FirstTime │ │ │ ├── CreateUserForm.tsx │ │ │ └── index.tsx │ │ │ └── Login │ │ │ ├── assets │ │ │ └── background.png │ │ │ └── index.tsx │ ├── plugins │ │ ├── components │ │ │ ├── PluginPageRenderer.tsx │ │ │ ├── PluginRoutes.tsx │ │ │ └── SlotRenderer.tsx │ │ ├── contexts │ │ │ └── plugin-context.tsx │ │ ├── interfaces │ │ │ └── plugin.interface.ts │ │ └── services │ │ │ ├── hook-registry.ts │ │ │ ├── plugin-loader.ts │ │ │ ├── plugin-registry.ts │ │ │ ├── route-registry.ts │ │ │ └── slot-registry.tsx │ ├── requestErrorConfig.ts │ ├── service-worker.js │ ├── services │ │ ├── request.ts │ │ └── rest │ │ │ ├── ansible-config │ │ │ └── ansible-config.ts │ │ │ ├── ansible-vaults │ │ │ └── ansible-vault.ts │ │ │ ├── ansible │ │ │ ├── ansible.galaxy.ts │ │ │ └── ansible.logs.ts │ │ │ ├── automations │ │ │ └── automations.ts │ │ │ ├── container-stacks │ │ │ ├── container-stacks.ts │ │ │ └── repositories.ts │ │ │ ├── containers │ │ │ ├── container-images.ts │ │ │ ├── container-networks.ts │ │ │ ├── container-registries.ts │ │ │ ├── container-statistics.ts │ │ │ ├── container-templates.ts │ │ │ ├── container-volumes.ts │ │ │ ├── containers-diagnostic.ts │ │ │ └── containers.ts │ │ │ ├── devices │ │ │ ├── device-credentials.ts │ │ │ └── devices.ts │ │ │ ├── diagnostic │ │ │ └── diagnostic.ts │ │ │ ├── index.ts │ │ │ ├── logs │ │ │ └── logs.ts │ │ │ ├── mcp │ │ │ └── mcp-settings.service.ts │ │ │ ├── notifications │ │ │ └── notifications.ts │ │ │ ├── playbooks │ │ │ ├── diagnostic.ts │ │ │ ├── playbooks.ts │ │ │ └── repositories.ts │ │ │ ├── plugin-store.service.ts │ │ │ ├── plugins.ts │ │ │ ├── remote-system-information │ │ │ └── diagnostic.ts │ │ │ ├── scheduler │ │ │ └── scheduler.ts │ │ │ ├── settings │ │ │ └── settings.ts │ │ │ ├── smart-failure │ │ │ └── smart-failure.ts │ │ │ ├── statistics │ │ │ └── stastistics.ts │ │ │ └── users │ │ │ └── users.ts │ ├── socket.ts │ ├── styles │ │ ├── colors.ts │ │ └── global.css │ ├── typings.d.ts │ └── utils │ │ ├── devicestatus.ts │ │ ├── ip.ts │ │ ├── string.ts │ │ ├── strings.ts │ │ ├── time.ts │ │ └── utils.less ├── tests │ ├── PlaybookExecutionHandler.test.ts │ ├── TerminalCore.test.tsx │ ├── components │ │ └── DeviceComponents │ │ │ └── SFTDrawer │ │ │ └── utils.test.ts │ ├── setupTests.ts │ └── utils │ │ ├── ip.test.ts │ │ ├── string.test.ts │ │ └── time.test.ts ├── tsconfig.json ├── types │ └── plugin.types.ts └── vitest.config.mts ├── doc-improvement.md ├── docker-compose.beta.yml ├── docker-compose.demo.dev.yml ├── docker-compose.demo.prod.yml ├── docker-compose.dev.yml ├── docker-compose.prod.yml ├── docker-compose.yml ├── getSSM.sh ├── jest.config.js ├── jsconfig.json ├── package-lock.json ├── package.json ├── prometheus ├── Dockerfile ├── entrypoint.sh └── prometheus.base.yml ├── proxy ├── Dockerfile ├── default.conf └── www │ └── index.html ├── release.json ├── server-demo ├── Dockerfile ├── eslint.config.mjs ├── nodemon.json ├── package-lock.json ├── package.json ├── src │ ├── data │ │ ├── ansible-conf.json │ │ ├── ansible-smart-failure.json │ │ ├── automations.json │ │ ├── availability.json │ │ ├── collection-detail.json │ │ ├── collection.json │ │ ├── containers.json │ │ ├── current-user.json │ │ ├── custom-stacks.json │ │ ├── device-auth.json │ │ ├── devices.json │ │ ├── dry-run.json │ │ ├── exec-logs.json │ │ ├── exec-statuses.json │ │ ├── images.json │ │ ├── logs-server.json │ │ ├── logs-task.json │ │ ├── networks.json │ │ ├── notifications.json │ │ ├── performance.json │ │ ├── playbooks-repo-git.json │ │ ├── playbooks-repo-local.json │ │ ├── playbooks-repository.json │ │ ├── playbooks.json │ │ ├── registries.json │ │ ├── templates.json │ │ └── volumes.json │ ├── index.ts │ ├── routes │ │ ├── ansible.ts │ │ ├── automations.ts │ │ ├── containers.ts │ │ ├── devices.ts │ │ ├── index.ts │ │ ├── logs.ts │ │ ├── notifications.ts │ │ ├── playbooks.ts │ │ ├── services.ts │ │ └── users.ts │ └── utils │ │ ├── ApiError.ts │ │ ├── ApiResponse.ts │ │ ├── AsyncHandler.ts │ │ └── ErrorHandler.ts └── tsconfig.json ├── server ├── .dockerignore ├── .editorconfig ├── .gitignore ├── .prettierignore ├── .prettierrc.json ├── CODE_GUIDELINES.md ├── Dockerfile ├── README.md ├── __mocks__ │ ├── fs.cjs │ └── fs │ │ └── promises.cjs ├── documentation │ ├── TODO.md │ ├── plans │ │ ├── DTO_Implementation_Plan.md │ │ ├── DTO_Recommendations.md │ │ ├── MODULE_INSPECTION_PLAN.md │ │ ├── end-to-end-testing-plan.md │ │ ├── module-isolation-plan.md │ │ └── oauth-oidc-plan.md │ └── swagger.md ├── eslint.config.mjs ├── jsconfig.json ├── nest-cli.json ├── nodemon.json ├── package-lock.json ├── package.json ├── src │ ├── App.ts │ ├── __tests__ │ │ ├── README.md │ │ ├── TEST_FAILURES.md │ │ ├── integration │ │ │ ├── controllers │ │ │ │ ├── rest │ │ │ │ │ ├── login.test.ts │ │ │ │ │ ├── settings.test.ts │ │ │ │ │ ├── user-test-setup.ts │ │ │ │ │ └── user.test.ts │ │ │ │ └── test-setup.ts │ │ │ ├── modules │ │ │ │ ├── devices │ │ │ │ │ └── devices.controller.test.ts │ │ │ │ ├── health │ │ │ │ │ ├── health.controller.spec.ts │ │ │ │ │ └── health.controller.test.ts │ │ │ │ └── test-setup.ts │ │ │ ├── ping.test.ts │ │ │ ├── server.ts │ │ │ ├── test-setup.ts │ │ │ └── test-utils │ │ │ │ ├── app.utils.ts │ │ │ │ ├── auth.utils.ts │ │ │ │ ├── db.utils.ts │ │ │ │ ├── device-test-helper.ts │ │ │ │ ├── request.utils.ts │ │ │ │ ├── route-discovery.ts │ │ │ │ ├── test-helper.ts │ │ │ │ └── user-test-helper.ts │ │ ├── test-setup.fixed.ts │ │ ├── test-setup.ts │ │ ├── vitest.config.mts │ │ └── vitest.setup.ts │ ├── ansible │ │ ├── 00000000-0000-0000-0000-000000000000 │ │ │ ├── agent │ │ │ │ ├── _checkDeviceBeforeAdd.json │ │ │ │ ├── _checkDeviceBeforeAdd.yml │ │ │ │ ├── _installAgent.json │ │ │ │ ├── _installAgent.yml │ │ │ │ ├── _reinstallAgent.json │ │ │ │ ├── _reinstallAgent.yml │ │ │ │ ├── _restartAgent.json │ │ │ │ ├── _restartAgent.yml │ │ │ │ ├── _retrieveAgentLogs.json │ │ │ │ ├── _retrieveAgentLogs.yml │ │ │ │ ├── _uninstallAgent.json │ │ │ │ ├── _uninstallAgent.yml │ │ │ │ ├── _updateAgent.json │ │ │ │ ├── _updateAgent.yml │ │ │ │ ├── group_vars │ │ │ │ │ └── all.yml │ │ │ │ └── roles │ │ │ │ │ ├── install_agent_docker │ │ │ │ │ └── tasks │ │ │ │ │ │ └── main.yml │ │ │ │ │ ├── install_agent_docker_conf │ │ │ │ │ ├── files │ │ │ │ │ │ └── docker-compose.yml │ │ │ │ │ └── tasks │ │ │ │ │ │ ├── copy_files.yml │ │ │ │ │ │ ├── create_directories.yml │ │ │ │ │ │ └── main.yml │ │ │ │ │ ├── install_agent_node │ │ │ │ │ └── tasks │ │ │ │ │ │ ├── check_node_npm.yml │ │ │ │ │ │ ├── install_git.yml │ │ │ │ │ │ ├── install_node.yml │ │ │ │ │ │ ├── main.yml │ │ │ │ │ │ ├── setup_agent.yml │ │ │ │ │ │ └── setup_pm2.yml │ │ │ │ │ ├── install_agent_node_v2 │ │ │ │ │ └── tasks │ │ │ │ │ │ ├── debug.yml │ │ │ │ │ │ ├── error_handling.yml │ │ │ │ │ │ ├── git_checkout.yml │ │ │ │ │ │ ├── main.yml │ │ │ │ │ │ ├── node_install.yml │ │ │ │ │ │ ├── npm_install.yml │ │ │ │ │ │ ├── nvm_install.yml │ │ │ │ │ │ ├── pm2_install.yml │ │ │ │ │ │ ├── pm2_start.yml │ │ │ │ │ │ ├── report_status.yml │ │ │ │ │ │ └── shell_detection.yml │ │ │ │ │ ├── install_docker │ │ │ │ │ └── tasks │ │ │ │ │ │ ├── check_docker.yml │ │ │ │ │ │ ├── install_docker.yml │ │ │ │ │ │ └── main.yml │ │ │ │ │ ├── remove_agent_docker_volume │ │ │ │ │ └── tasks │ │ │ │ │ │ └── main.yml │ │ │ │ │ ├── restart_agent_docker │ │ │ │ │ └── tasks │ │ │ │ │ │ └── main.yml │ │ │ │ │ ├── restart_agent_node │ │ │ │ │ └── tasks │ │ │ │ │ │ └── main.yml │ │ │ │ │ ├── start_agent_docker │ │ │ │ │ └── tasks │ │ │ │ │ │ └── main.yml │ │ │ │ │ ├── stop_agent_docker │ │ │ │ │ └── tasks │ │ │ │ │ │ └── main.yml │ │ │ │ │ ├── uninstall_agent_docker │ │ │ │ │ └── tasks │ │ │ │ │ │ └── main.yml │ │ │ │ │ └── uninstall_agent_node │ │ │ │ │ └── tasks │ │ │ │ │ └── main.yml │ │ │ ├── device │ │ │ │ ├── _ping.json │ │ │ │ ├── _ping.yml │ │ │ │ ├── _reboot.json │ │ │ │ ├── _reboot.yml │ │ │ │ ├── _upgrade.json │ │ │ │ ├── _upgrade.yml │ │ │ │ └── roles │ │ │ │ │ └── upgrade_host_package │ │ │ │ │ ├── debian.yml │ │ │ │ │ ├── main.yml │ │ │ │ │ └── rhel.yml │ │ │ └── docker │ │ │ │ ├── _createDockerNetwork.json │ │ │ │ ├── _createDockerNetwork.yml │ │ │ │ ├── _createDockerVolume.json │ │ │ │ ├── _createDockerVolume.yml │ │ │ │ ├── _dockerCompose.json │ │ │ │ └── _dockerCompose.yml │ │ ├── 00000000-0000-0000-0000-000000000001 │ │ │ ├── installers │ │ │ │ ├── install-docker.yml │ │ │ │ └── install-proxmox.yml │ │ │ ├── nas-updaters │ │ │ │ ├── update-asustor.yml │ │ │ │ ├── update-qnap.yml │ │ │ │ ├── update-synology.yml │ │ │ │ └── update-truenas.yml │ │ │ ├── security │ │ │ │ ├── new-ansible-root-user.yml │ │ │ │ ├── secure-docker-socket.yml │ │ │ │ └── secure-with-iptables.yml │ │ │ └── utils │ │ │ │ ├── change-fqdn.yml │ │ │ │ ├── fact-scan.yml │ │ │ │ ├── ping-ssm-api-url.json │ │ │ │ └── ping-ssm-api-url.yml │ │ ├── default-ansible.cfg │ │ ├── env │ │ │ └── cmdline │ │ ├── inventory │ │ │ └── inventory.py │ │ ├── requirements.txt │ │ ├── ssm-ansible-run.py │ │ ├── ssm-ansible-vault-password-client.py │ │ └── test_ssm_ansible_run.py │ ├── app.module.ts │ ├── config.ts │ ├── core │ │ ├── bootstrap │ │ │ ├── bootstrap.module.ts │ │ │ └── bootstrap.service.ts │ │ └── events │ │ │ ├── __tests__ │ │ │ └── event-emitter.service.spec.ts │ │ │ ├── event-emitter.service.ts │ │ │ ├── events.module.ts │ │ │ ├── events.ts │ │ │ └── restart-server.event.ts │ ├── data │ │ └── static │ │ │ └── templates.json │ ├── decorators │ │ ├── public.decorator.ts │ │ ├── roles.decorator.ts │ │ ├── skip-throttle.decorator.ts │ │ └── user.decorator.ts │ ├── infrastructure │ │ ├── README.md │ │ ├── adapters │ │ │ ├── git │ │ │ │ ├── errors │ │ │ │ │ ├── errors.util.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── index.ts │ │ │ │ ├── interfaces │ │ │ │ │ ├── git.interface.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── services │ │ │ │ │ ├── clone.service.ts │ │ │ │ │ ├── commit-and-sync.service.ts │ │ │ │ │ ├── force-pull.service.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── init-git.service.ts │ │ │ │ │ ├── inspect.service.ts │ │ │ │ │ └── sync.service.ts │ │ │ │ └── utils │ │ │ │ │ ├── credential.util.ts │ │ │ │ │ ├── default-info.util.ts │ │ │ │ │ ├── git.util.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── init.util.ts │ │ │ ├── proxmox │ │ │ │ ├── CREDIT.md │ │ │ │ ├── index.ts │ │ │ │ └── services │ │ │ │ │ ├── constructor.service.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── proxmox-engine.service.ts │ │ │ │ │ ├── proxy.service.ts │ │ │ │ │ └── qm-monitor.service.ts │ │ │ └── ssh │ │ │ │ ├── __tests__ │ │ │ │ └── ssh-credentials.adapter.spec.ts │ │ │ │ ├── axios-ssh.adapter.ts │ │ │ │ ├── custom-agent.adapter.ts │ │ │ │ ├── index.ts │ │ │ │ ├── ssh-credentials.adapter.mock.ts │ │ │ │ └── ssh-credentials.adapter.ts │ │ ├── auth │ │ │ ├── README.md │ │ │ ├── auth.module.ts │ │ │ └── strategies │ │ │ │ ├── auth.strategy.ts │ │ │ │ ├── bearer.strategy.ts │ │ │ │ ├── jwt-auth-guard.interface.ts │ │ │ │ ├── jwt-auth.guard.ts │ │ │ │ ├── jwt-strategy.interface.ts │ │ │ │ └── jwt.strategy.ts │ │ ├── common │ │ │ ├── ansible │ │ │ │ ├── __tests__ │ │ │ │ │ ├── ansible-configuration.util.spec.ts │ │ │ │ │ └── test-setup.ts │ │ │ │ ├── ansible-configuration.util.ts │ │ │ │ ├── ansible-task.util.ts │ │ │ │ └── index.ts │ │ │ ├── directory-tree │ │ │ │ ├── README.md │ │ │ │ ├── __tests__ │ │ │ │ │ ├── constants.ts │ │ │ │ │ ├── depth │ │ │ │ │ │ ├── fixtureFirstDepth.ts │ │ │ │ │ │ ├── fixtureSecondDepth.ts │ │ │ │ │ │ └── fixtureZeroDepth.ts │ │ │ │ │ ├── directory-tree.util.spec.ts │ │ │ │ │ ├── fixture.ts │ │ │ │ │ ├── fixtureExclude.ts │ │ │ │ │ ├── fixtureMultipleExclude.ts │ │ │ │ │ └── test_data │ │ │ │ │ │ ├── file_a.txt │ │ │ │ │ │ ├── file_b.txt │ │ │ │ │ │ ├── some_dir │ │ │ │ │ │ ├── another_dir │ │ │ │ │ │ │ ├── file_a.txt │ │ │ │ │ │ │ └── file_b.txt │ │ │ │ │ │ ├── file_a.txt │ │ │ │ │ │ └── file_b.txt │ │ │ │ │ │ └── some_dir_2 │ │ │ │ │ │ └── .gitkeep │ │ │ │ ├── directory-tree.util.ts │ │ │ │ └── index.ts │ │ │ ├── dns │ │ │ │ ├── dns.util.ts │ │ │ │ └── index.ts │ │ │ ├── docker │ │ │ │ ├── __tests__ │ │ │ │ │ ├── docker-compose-json-transformer.util.spec.ts │ │ │ │ │ └── docker-compose.util.spec.ts │ │ │ │ ├── docker-compose-json-transformer.util.ts │ │ │ │ ├── docker-compose.util.ts │ │ │ │ ├── index.ts │ │ │ │ └── utils.ts │ │ │ ├── files │ │ │ │ ├── index.ts │ │ │ │ └── recursive-find.util.ts │ │ │ ├── index.ts │ │ │ ├── query │ │ │ │ ├── __tests__ │ │ │ │ │ ├── filter.util.spec.ts │ │ │ │ │ ├── mock-pagination.util.ts │ │ │ │ │ ├── pagination.util.spec.ts │ │ │ │ │ ├── sorter.util.spec.ts │ │ │ │ │ ├── test-setup.fixed.ts │ │ │ │ │ ├── test-setup.ts │ │ │ │ │ └── utils.spec.ts │ │ │ │ ├── filter.util.ts │ │ │ │ ├── index.ts │ │ │ │ ├── pagination.util.ts │ │ │ │ └── sorter.util.ts │ │ │ ├── redis │ │ │ │ ├── index.ts │ │ │ │ └── redis-info.util.ts │ │ │ └── utils │ │ │ │ ├── index.ts │ │ │ │ └── utils.ts │ │ ├── decorators │ │ │ ├── api-error-response.decorator.ts │ │ │ ├── api-standard-response.decorator.ts │ │ │ ├── api-success-response.decorator.ts │ │ │ └── swagger.decorators.ts │ │ ├── documentation │ │ │ └── example-error-handling.md │ │ ├── exceptions │ │ │ ├── app-exceptions.ts │ │ │ ├── exception-factory.ts │ │ │ └── index.ts │ │ ├── filters │ │ │ ├── api-exception.filter.ts │ │ │ └── http-exception.filter.ts │ │ ├── index.ts │ │ ├── interceptors │ │ │ ├── error-transformer.interceptor.ts │ │ │ └── transform.interceptor.ts │ │ ├── models │ │ │ ├── api-response.model.ts │ │ │ └── paginated-response.dto.ts │ │ ├── plugins │ │ │ ├── README.md │ │ │ ├── decorators │ │ │ │ └── plugins.decorators.ts │ │ │ ├── plugin-system.ts │ │ │ ├── plugins.controller.ts │ │ │ ├── plugins.module.ts │ │ │ └── store │ │ │ │ ├── interfaces │ │ │ │ └── plugin-store-info.interface.ts │ │ │ │ ├── plugin-store.controller.ts │ │ │ │ ├── plugin-store.module.ts │ │ │ │ ├── plugin-store.service.ts │ │ │ │ └── schemas │ │ │ │ └── plugin-store-config.schema.ts │ │ ├── prometheus │ │ │ ├── prometheus.interface.ts │ │ │ ├── prometheus.provider.ts │ │ │ ├── prometheus.service.ts │ │ │ └── types │ │ │ │ ├── filters.types.ts │ │ │ │ └── prometheus.types.ts │ │ ├── security │ │ │ ├── audit │ │ │ │ ├── audit-log.module.ts │ │ │ │ ├── audit-log.service.ts │ │ │ │ ├── audit.interceptor.ts │ │ │ │ └── schemas │ │ │ │ │ └── audit-log.schema.ts │ │ │ ├── csp │ │ │ │ └── csp.middleware.ts │ │ │ ├── index.ts │ │ │ ├── roles │ │ │ │ ├── permission.service.ts │ │ │ │ ├── resource-action.decorator.ts │ │ │ │ └── roles.guard.ts │ │ │ ├── throttler │ │ │ │ └── throttler.module.ts │ │ │ └── vault-crypto │ │ │ │ ├── __tests__ │ │ │ │ ├── binascii.util.spec.ts │ │ │ │ ├── constants.ts │ │ │ │ ├── pkcs7.util.spec.ts │ │ │ │ ├── test-setup.ts │ │ │ │ └── vault.service.spec.ts │ │ │ │ ├── index.ts │ │ │ │ ├── services │ │ │ │ ├── index.ts │ │ │ │ └── vault.service.ts │ │ │ │ ├── types │ │ │ │ ├── index.d.ts │ │ │ │ └── index.ts │ │ │ │ └── utils │ │ │ │ ├── binascii.util.ts │ │ │ │ ├── index.ts │ │ │ │ └── pkcs7.util.ts │ │ ├── ssh │ │ │ ├── services │ │ │ │ └── ssh-connection.service.ts │ │ │ └── ssh-infrastructure.module.ts │ │ ├── system │ │ │ └── system.service.ts │ │ └── websocket-auth │ │ │ ├── ws-auth.guard.ts │ │ │ └── ws-auth.module.ts │ ├── logger.ts │ ├── main.ts │ ├── modules │ │ ├── README.md │ │ ├── ansible-config │ │ │ ├── README.md │ │ │ ├── __tests__ │ │ │ │ ├── application │ │ │ │ │ └── services │ │ │ │ │ │ ├── ansible-config-test-setup.ts │ │ │ │ │ │ ├── ansible-config.service.spec.ts │ │ │ │ │ │ └── mock-ansible-config.service.ts │ │ │ │ ├── presentation │ │ │ │ │ └── controllers │ │ │ │ │ │ └── ansible-config.controller.spec.ts │ │ │ │ └── test-setup.ts │ │ │ ├── ansible-config.module.ts │ │ │ ├── application │ │ │ │ └── services │ │ │ │ │ └── ansible-config.service.ts │ │ │ ├── constants.ts │ │ │ ├── domain │ │ │ │ └── interfaces │ │ │ │ │ └── ansible-config-service.interface.ts │ │ │ ├── index.ts │ │ │ └── presentation │ │ │ │ ├── controllers │ │ │ │ └── ansible-config.controller.ts │ │ │ │ ├── decorators │ │ │ │ └── ansible-config.decorators.ts │ │ │ │ ├── dtos │ │ │ │ └── ansible-config.dto.ts │ │ │ │ └── interfaces │ │ │ │ └── config.interface.ts │ │ ├── ansible-vaults │ │ │ ├── README.md │ │ │ ├── __tests__ │ │ │ │ ├── application │ │ │ │ │ └── services │ │ │ │ │ │ ├── ansible-vault.service.spec.ts │ │ │ │ │ │ └── vault-crypto.service.spec.ts │ │ │ │ ├── infrastructure │ │ │ │ │ └── repositories │ │ │ │ │ │ └── ansible-vault.repository.spec.ts │ │ │ │ ├── mocks │ │ │ │ │ ├── infrastructure.ts │ │ │ │ │ ├── vault-crypto.service.mock.ts │ │ │ │ │ └── vault.service.ts │ │ │ │ ├── presentation │ │ │ │ │ └── controllers │ │ │ │ │ │ └── ansible-vaults.controller.spec.ts │ │ │ │ └── test-setup.ts │ │ │ ├── ansible-vaults.module.ts │ │ │ ├── application │ │ │ │ └── services │ │ │ │ │ ├── ansible-vault.service.ts │ │ │ │ │ └── vault-crypto.service.ts │ │ │ ├── domain │ │ │ │ ├── entities │ │ │ │ │ └── ansible-vault.entity.ts │ │ │ │ ├── interfaces │ │ │ │ │ ├── ansible-vault-service.interface.ts │ │ │ │ │ └── vault-crypto-service.interface.ts │ │ │ │ └── repositories │ │ │ │ │ └── ansible-vault-repository.interface.ts │ │ │ ├── index.ts │ │ │ ├── infrastructure │ │ │ │ ├── mappers │ │ │ │ │ └── ansible-vault-repository.mapper.ts │ │ │ │ ├── repositories │ │ │ │ │ └── ansible-vault.repository.ts │ │ │ │ └── schemas │ │ │ │ │ └── ansible-vault.schema.ts │ │ │ └── presentation │ │ │ │ ├── controllers │ │ │ │ └── ansible-vaults.controller.ts │ │ │ │ ├── decorators │ │ │ │ └── ansible-vaults.decorators.ts │ │ │ │ ├── dto │ │ │ │ └── ansible-vault.dto.ts │ │ │ │ └── dtos │ │ │ │ └── ansible-vault.dto.ts │ │ ├── ansible │ │ │ ├── README.md │ │ │ ├── __tests__ │ │ │ │ ├── application │ │ │ │ │ └── services │ │ │ │ │ │ ├── ansible-command-builder.service.spec.ts │ │ │ │ │ │ ├── ansible-galaxy-command.service.spec.ts │ │ │ │ │ │ ├── ansible-hooks.service.spec.ts │ │ │ │ │ │ ├── extravars │ │ │ │ │ │ ├── extra-vars-transformer.service.spec.ts │ │ │ │ │ │ ├── extra-vars.service.spec.ts │ │ │ │ │ │ └── simple.test.ts │ │ │ │ │ │ ├── galaxy.service.spec.ts │ │ │ │ │ │ ├── inventory-transformer.service.spec.ts │ │ │ │ │ │ └── task-logs.service.spec.ts │ │ │ │ ├── infrastructure │ │ │ │ │ └── repositories │ │ │ │ │ │ └── ansible-task.repository.spec.ts │ │ │ │ └── test-setup.ts │ │ │ ├── ansible.module.ts │ │ │ ├── application │ │ │ │ └── services │ │ │ │ │ ├── ansible-command-builder.service.ts │ │ │ │ │ ├── ansible-command.service.ts │ │ │ │ │ ├── ansible-galaxy-command.service.ts │ │ │ │ │ ├── ansible-hooks.service.ts │ │ │ │ │ ├── extra-vars-transformer.service.ts │ │ │ │ │ ├── extra-vars.service.ts │ │ │ │ │ ├── galaxy.service.ts │ │ │ │ │ ├── inventory-transformer.service.ts │ │ │ │ │ └── task-logs.service.ts │ │ │ ├── domain │ │ │ │ ├── entities │ │ │ │ │ ├── ansible-task-status.entity.ts │ │ │ │ │ ├── ansible-task-status.interface.ts │ │ │ │ │ ├── ansible-task.entity.ts │ │ │ │ │ └── ansible-task.interface.ts │ │ │ │ ├── interfaces │ │ │ │ │ ├── ansible-command-builder-service.interface.ts │ │ │ │ │ ├── ansible-command-service.interface.ts │ │ │ │ │ ├── ansible-galaxy-command-service.interface.ts │ │ │ │ │ ├── ansible-hooks-service.interface.ts │ │ │ │ │ ├── extra-vars-service.interface.ts │ │ │ │ │ ├── extra-vars-transformer-service.interface.ts │ │ │ │ │ ├── galaxy-service.interface.ts │ │ │ │ │ ├── inventory-transformer-service.interface.ts │ │ │ │ │ └── task-logs-service.interface.ts │ │ │ │ └── repositories │ │ │ │ │ ├── ansible-task-status.repository.interface.ts │ │ │ │ │ └── ansible-task.repository.interface.ts │ │ │ ├── index.ts │ │ │ ├── infrastructure │ │ │ │ ├── repositories │ │ │ │ │ ├── ansible-task-status.repository.ts │ │ │ │ │ └── ansible-task.repository.ts │ │ │ │ └── schemas │ │ │ │ │ ├── ansible-task-status.schema.ts │ │ │ │ │ └── ansible-task.schema.ts │ │ │ └── presentation │ │ │ │ ├── controllers │ │ │ │ ├── ansible-galaxy.controller.ts │ │ │ │ ├── ansible-hooks.controller.ts │ │ │ │ ├── ansible-inventory.controller.ts │ │ │ │ └── ansible-task-logs.controller.ts │ │ │ │ ├── decorators │ │ │ │ ├── ansible-hooks.decorators.ts │ │ │ │ ├── ansible-inventory.decorator.ts │ │ │ │ └── galaxy.decorators.ts │ │ │ │ ├── dtos │ │ │ │ ├── galaxy-collection.dto.ts │ │ │ │ ├── galaxy-response.dto.ts │ │ │ │ ├── get-inventory-body.dto.ts │ │ │ │ ├── get-inventory-query.dto.ts │ │ │ │ ├── task-event.dto.ts │ │ │ │ ├── task-hook.dto.ts │ │ │ │ ├── task-logs-query.dto.ts │ │ │ │ └── task-response.dto.ts │ │ │ │ └── interfaces │ │ │ │ └── api-response.interface.ts │ │ ├── automations │ │ │ ├── README.md │ │ │ ├── __tests__ │ │ │ │ ├── application │ │ │ │ │ └── services │ │ │ │ │ │ ├── automation-engine.service.spec.ts │ │ │ │ │ │ └── automations.service.spec.ts │ │ │ │ ├── automations.module.spec.ts │ │ │ │ └── domain │ │ │ │ │ └── components │ │ │ │ │ ├── actions │ │ │ │ │ ├── abstract-action.component.spec.ts │ │ │ │ │ ├── docker-action.component.spec.ts │ │ │ │ │ ├── docker-volume-action.component.spec.ts │ │ │ │ │ └── playbook-action.component.spec.ts │ │ │ │ │ ├── automation.component.spec.ts │ │ │ │ │ └── triggers │ │ │ │ │ ├── abstract-trigger.component.spec.ts │ │ │ │ │ └── cron-trigger.component.spec.ts │ │ │ ├── application │ │ │ │ └── services │ │ │ │ │ ├── automations.service.ts │ │ │ │ │ ├── components │ │ │ │ │ ├── actions │ │ │ │ │ │ ├── abstract-action.component.ts │ │ │ │ │ │ ├── docker-action.component.ts │ │ │ │ │ │ ├── docker-volume-action.component.ts │ │ │ │ │ │ └── playbook-action.component.ts │ │ │ │ │ ├── automation.component.ts │ │ │ │ │ └── triggers │ │ │ │ │ │ ├── abstract-trigger.component.ts │ │ │ │ │ │ └── cron-trigger.component.ts │ │ │ │ │ └── engine │ │ │ │ │ └── automation-engine.service.ts │ │ │ ├── automations.module.ts │ │ │ ├── domain │ │ │ │ ├── entities │ │ │ │ │ └── automation.entity.ts │ │ │ │ ├── interfaces │ │ │ │ │ ├── automation-engine-service.interface.ts │ │ │ │ │ └── automations-service.interface.ts │ │ │ │ └── repositories │ │ │ │ │ └── automation.repository.interface.ts │ │ │ ├── index.ts │ │ │ ├── infrastructure │ │ │ │ ├── repositories │ │ │ │ │ └── automation.repository.ts │ │ │ │ └── schemas │ │ │ │ │ └── automation.schema.ts │ │ │ └── presentation │ │ │ │ ├── controllers │ │ │ │ └── automations.controller.ts │ │ │ │ ├── decorators │ │ │ │ └── automations.decorators.ts │ │ │ │ └── dtos │ │ │ │ ├── create-automation.dto.ts │ │ │ │ └── update-automation.dto.ts │ │ ├── common-test-helpers.ts │ │ ├── container-stacks │ │ │ ├── README.md │ │ │ ├── __tests__ │ │ │ │ ├── application │ │ │ │ │ ├── interfaces │ │ │ │ │ │ ├── container-repository-component-service.interface.spec.ts │ │ │ │ │ │ ├── container-stacks-repository-engine-service.interface.spec.ts │ │ │ │ │ │ └── container-stacks-service.interface.spec.ts │ │ │ │ │ └── services │ │ │ │ │ │ ├── container-repository-component.service.spec.ts │ │ │ │ │ │ ├── container-stacks-repository-engine-service.spec.ts │ │ │ │ │ │ └── container-stacks.service.spec.ts │ │ │ │ ├── container-stacks.module.spec.ts │ │ │ │ ├── domain │ │ │ │ │ ├── entities │ │ │ │ │ │ ├── container-custom-stack.entity.spec.ts │ │ │ │ │ │ └── repository-config.entity.spec.ts │ │ │ │ │ └── repositories │ │ │ │ │ │ ├── container-custom-stack-repository-repository.interface.spec.ts │ │ │ │ │ │ └── container-custom-stack-repository.interface.spec.ts │ │ │ │ ├── infrastructure │ │ │ │ │ ├── mappers │ │ │ │ │ │ ├── container-custom-stack-repository.mapper.spec.ts │ │ │ │ │ │ └── container-custom-stack.mapper.spec.ts │ │ │ │ │ └── repositories │ │ │ │ │ │ ├── container-custom-stack.repository.spec.ts │ │ │ │ │ │ ├── container-custom-stacks-repository.repository.spec.ts │ │ │ │ │ │ └── test-setup.ts │ │ │ │ ├── presentation │ │ │ │ │ └── controllers │ │ │ │ │ │ └── container-stacks.controller.spec.ts │ │ │ │ └── test-setup.ts │ │ │ ├── application │ │ │ │ └── services │ │ │ │ │ ├── container-repository-component.service.ts │ │ │ │ │ ├── container-stacks-repository-engine-service.ts │ │ │ │ │ └── container-stacks.service.ts │ │ │ ├── container-stacks.module.ts │ │ │ ├── domain │ │ │ │ ├── entities │ │ │ │ │ ├── container-custom-stack.entity.ts │ │ │ │ │ └── repository-config.entity.ts │ │ │ │ ├── interfaces │ │ │ │ │ ├── container-repository-component-service.interface.ts │ │ │ │ │ ├── container-stacks-repository-engine-service.interface.ts │ │ │ │ │ └── container-stacks-service.interface.ts │ │ │ │ └── repositories │ │ │ │ │ ├── container-custom-stack-repository-repository.interface.ts │ │ │ │ │ └── container-custom-stack-repository.interface.ts │ │ │ ├── index.ts │ │ │ ├── infrastructure │ │ │ │ ├── mappers │ │ │ │ │ ├── container-custom-stack-repository.mapper.ts │ │ │ │ │ └── container-custom-stack.mapper.ts │ │ │ │ ├── repositories │ │ │ │ │ ├── container-custom-stack.repository.ts │ │ │ │ │ └── container-custom-stacks-repository.repository.ts │ │ │ │ └── schemas │ │ │ │ │ ├── container-custom-stack-repository.schema.ts │ │ │ │ │ └── container-custom-stack.schema.ts │ │ │ └── presentation │ │ │ │ ├── controllers │ │ │ │ ├── container-stack-repositories.controller.ts │ │ │ │ └── container-stacks.controller.ts │ │ │ │ ├── decorators │ │ │ │ ├── container-stack-repositories.decorators.ts │ │ │ │ └── container-stacks.decorators.ts │ │ │ │ └── dtos │ │ │ │ ├── create-container-stack-repository.dto.ts │ │ │ │ ├── create-container-stack.dto.ts │ │ │ │ └── update-container-stack-repository.dto.ts │ │ ├── containers │ │ │ ├── CREDIT.md │ │ │ ├── README.md │ │ │ ├── __tests__ │ │ │ │ ├── __mocks__ │ │ │ │ │ └── utils.ts │ │ │ │ ├── application │ │ │ │ │ └── services │ │ │ │ │ │ ├── components │ │ │ │ │ │ ├── Acr.spec.ts │ │ │ │ │ │ ├── Component.spec.ts │ │ │ │ │ │ ├── Custom.spec.ts │ │ │ │ │ │ ├── Docker.spec.ts │ │ │ │ │ │ ├── Ecr.spec.ts │ │ │ │ │ │ ├── Forjejo.spec.ts │ │ │ │ │ │ ├── Gcr.spec.ts │ │ │ │ │ │ ├── Ghcr.spec.ts │ │ │ │ │ │ ├── Gitea.spec.ts │ │ │ │ │ │ ├── Gitlab.spec.ts │ │ │ │ │ │ ├── Hub.spec.ts │ │ │ │ │ │ ├── Lscr.spec.ts │ │ │ │ │ │ ├── Quay.spec.ts │ │ │ │ │ │ ├── Registry.spec.ts │ │ │ │ │ │ ├── abstract-registry.component.spec.ts │ │ │ │ │ │ ├── component-factory.service.spec.ts │ │ │ │ │ │ ├── component-mock.ts │ │ │ │ │ │ ├── docker-hub-registry.component.spec.ts │ │ │ │ │ │ ├── ecr-mock.ts │ │ │ │ │ │ ├── full-component-mock.ts │ │ │ │ │ │ ├── gcr-mock.ts │ │ │ │ │ │ ├── ghcr-mock.ts │ │ │ │ │ │ ├── gitea-mock.ts │ │ │ │ │ │ ├── gitlab-mock.ts │ │ │ │ │ │ ├── hub-mock.ts │ │ │ │ │ │ ├── kind-mock.ts │ │ │ │ │ │ ├── lscr-mock.ts │ │ │ │ │ │ ├── mock-acr-registry.component.ts │ │ │ │ │ │ ├── mock-component │ │ │ │ │ │ ├── mock-registry-components.ts │ │ │ │ │ │ ├── mock-utils.ts │ │ │ │ │ │ ├── quay-mock.ts │ │ │ │ │ │ ├── samples │ │ │ │ │ │ │ ├── coercedSemver.json │ │ │ │ │ │ │ ├── notSemver.json │ │ │ │ │ │ │ └── semver.json │ │ │ │ │ │ ├── tag.spec.ts │ │ │ │ │ │ ├── utils.spec.ts │ │ │ │ │ │ └── watcher │ │ │ │ │ │ │ └── providers │ │ │ │ │ │ │ └── proxmox │ │ │ │ │ │ │ └── proxmox-watcher.component.spec.ts │ │ │ │ │ │ ├── container-service-integration.spec.ts │ │ │ │ │ │ └── engine │ │ │ │ │ │ └── watcher-engine-integration.spec.ts │ │ │ │ ├── samples │ │ │ │ │ ├── coercedSemver.json │ │ │ │ │ ├── notSemver.json │ │ │ │ │ └── semver.json │ │ │ │ ├── test-setup.fixed.ts │ │ │ │ ├── test-setup.ts │ │ │ │ └── utils │ │ │ │ │ ├── tag.service.spec.ts │ │ │ │ │ └── utils.service.spec.ts │ │ │ ├── application │ │ │ │ └── services │ │ │ │ │ ├── components │ │ │ │ │ ├── component-factory.service.ts │ │ │ │ │ ├── core │ │ │ │ │ │ └── constants.ts │ │ │ │ │ ├── registry │ │ │ │ │ │ ├── abstract-registry.component.ts │ │ │ │ │ │ ├── acr-registry.component.ts │ │ │ │ │ │ ├── custom-registry.component.ts │ │ │ │ │ │ ├── docker-hub-registry.component.ts │ │ │ │ │ │ ├── ecr-registry.component.ts │ │ │ │ │ │ ├── forgejo-registry.component.ts │ │ │ │ │ │ ├── gcr-registry.component.ts │ │ │ │ │ │ ├── ghcr-registry.component.ts │ │ │ │ │ │ ├── gitea-registry.component.ts │ │ │ │ │ │ ├── gitlab-registry.component.ts │ │ │ │ │ │ ├── lscr-registry.component.ts │ │ │ │ │ │ ├── quay-registry.component.ts │ │ │ │ │ │ └── registry-component-factory.service.ts │ │ │ │ │ └── watcher │ │ │ │ │ │ ├── abstract-watcher.component.ts │ │ │ │ │ │ ├── providers │ │ │ │ │ │ ├── docker │ │ │ │ │ │ │ ├── abstract-docker-images.component.ts │ │ │ │ │ │ │ ├── abstract-docker-listener.component.ts │ │ │ │ │ │ │ ├── abstract-docker-logs.component.ts │ │ │ │ │ │ │ ├── abstract-docker-networks.component.ts │ │ │ │ │ │ │ ├── abstract-docker-volumes.component.ts │ │ │ │ │ │ │ ├── docker-watcher-factory.service.ts │ │ │ │ │ │ │ └── docker-watcher.component.ts │ │ │ │ │ │ └── proxmox │ │ │ │ │ │ │ └── proxmox-watcher.component.ts │ │ │ │ │ │ └── watcher-component-factory.service.ts │ │ │ │ │ ├── container-images.service.ts │ │ │ │ │ ├── container-logs.service.ts │ │ │ │ │ ├── container-networks.service.ts │ │ │ │ │ ├── container-registries.service.ts │ │ │ │ │ ├── container-stats.service.ts │ │ │ │ │ ├── container-templates.service.ts │ │ │ │ │ ├── container-volumes.service.ts │ │ │ │ │ ├── container.service.ts │ │ │ │ │ ├── data │ │ │ │ │ └── providers-default.constants.ts │ │ │ │ │ └── engine │ │ │ │ │ └── watcher-engine.service.ts │ │ │ ├── constants.ts │ │ │ ├── containers.module.ts │ │ │ ├── domain │ │ │ │ ├── components │ │ │ │ │ ├── component.interface.ts │ │ │ │ │ ├── docker-watcher.interface.ts │ │ │ │ │ ├── kind.enum.ts │ │ │ │ │ ├── registry.interface.ts │ │ │ │ │ └── watcher.interface.ts │ │ │ │ ├── entities │ │ │ │ │ ├── container-image.entity.ts │ │ │ │ │ ├── container-network.entity.ts │ │ │ │ │ ├── container-registry.entity.ts │ │ │ │ │ ├── container-volume.entity.ts │ │ │ │ │ ├── container.entity.ts │ │ │ │ │ └── proxmox-container.entity.ts │ │ │ │ ├── enums │ │ │ │ │ └── container-health.enum.ts │ │ │ │ ├── interfaces │ │ │ │ │ ├── container-images-service.interface.ts │ │ │ │ │ ├── container-logs-service.interface.ts │ │ │ │ │ ├── container-networks-service.interface.ts │ │ │ │ │ ├── container-registries-service.interface.ts │ │ │ │ │ ├── container-service.interface.ts │ │ │ │ │ ├── container-stats-service.interface.ts │ │ │ │ │ ├── container-templates-service.interface.ts │ │ │ │ │ ├── container-volumes-service.interface.ts │ │ │ │ │ └── watcher-engine-service.interface.ts │ │ │ │ └── repositories │ │ │ │ │ ├── container-image-repository.interface.ts │ │ │ │ │ ├── container-network-repository.interface.ts │ │ │ │ │ ├── container-registry-repository.interface.ts │ │ │ │ │ ├── container-repository.interface.ts │ │ │ │ │ ├── container-volume-repository.interface.ts │ │ │ │ │ └── proxmox-container.repository.interface.ts │ │ │ ├── index.ts │ │ │ ├── infrastructure │ │ │ │ ├── mappers │ │ │ │ │ ├── container-image.mapper.ts │ │ │ │ │ ├── container-network.mapper.ts │ │ │ │ │ ├── container-registry.mapper.ts │ │ │ │ │ ├── container-volume.mapper.ts │ │ │ │ │ └── container.mapper.ts │ │ │ │ ├── repositories │ │ │ │ │ ├── container-image.repository.ts │ │ │ │ │ ├── container-network.repository.ts │ │ │ │ │ ├── container-registry.repository.ts │ │ │ │ │ ├── container-volume.repository.ts │ │ │ │ │ ├── container.repository.ts │ │ │ │ │ └── proxmox-container.repository.ts │ │ │ │ └── schemas │ │ │ │ │ ├── container-image.schema.ts │ │ │ │ │ ├── container-network.schema.ts │ │ │ │ │ ├── container-registry.schema.ts │ │ │ │ │ ├── container-volume.schema.ts │ │ │ │ │ ├── container.schema.ts │ │ │ │ │ └── proxmox-container.schema.ts │ │ │ ├── presentation │ │ │ │ ├── controllers │ │ │ │ │ ├── container-diagnostic.controller.ts │ │ │ │ │ ├── container-images.controller.ts │ │ │ │ │ ├── container-networks.controller.ts │ │ │ │ │ ├── container-registries.controller.ts │ │ │ │ │ ├── container-stats.controller.ts │ │ │ │ │ ├── container-templates.controller.ts │ │ │ │ │ ├── container-volumes.controller.ts │ │ │ │ │ ├── containers-microservice.controller.ts │ │ │ │ │ └── containers.controller.ts │ │ │ │ ├── decorators │ │ │ │ │ ├── container-diagnostic.decorators.ts │ │ │ │ │ ├── container-images.decorators.ts │ │ │ │ │ ├── container-networks.decorators.ts │ │ │ │ │ ├── container-registries.decorators.ts │ │ │ │ │ ├── container-stats.decorators.ts │ │ │ │ │ ├── container-templates.decorators.ts │ │ │ │ │ ├── container-volumes.decorators.ts │ │ │ │ │ └── container.decorators.ts │ │ │ │ ├── dtos │ │ │ │ │ ├── container-action.dto.ts │ │ │ │ │ ├── container-logs.dto.ts │ │ │ │ │ ├── container-query-params.dto.ts │ │ │ │ │ ├── container-query.dto.ts │ │ │ │ │ ├── container-registry.dto.ts │ │ │ │ │ ├── container-response.dto.ts │ │ │ │ │ ├── container-stats.dto.ts │ │ │ │ │ ├── container-templates.dto.ts │ │ │ │ │ ├── create-container.dto.ts │ │ │ │ │ ├── create-network.dto.ts │ │ │ │ │ ├── create-volume.dto.ts │ │ │ │ │ ├── paginated-response.dto.ts │ │ │ │ │ ├── pre-check-docker-connection.dto.ts │ │ │ │ │ └── update-container.dto.ts │ │ │ │ └── gateways │ │ │ │ │ ├── container-logs.gateway.ts │ │ │ │ │ └── container-volumes.gateway.ts │ │ │ ├── types.ts │ │ │ └── utils │ │ │ │ ├── label.ts │ │ │ │ ├── tag.ts │ │ │ │ └── utils.ts │ │ ├── devices │ │ │ ├── README.md │ │ │ ├── __tests__ │ │ │ │ ├── application │ │ │ │ │ └── services │ │ │ │ │ │ └── device-auth.service.spec.ts │ │ │ │ └── infrastructure │ │ │ │ │ └── repositories │ │ │ │ │ ├── device-auth.repository.spec.ts │ │ │ │ │ └── device.repository.spec.ts │ │ │ ├── application │ │ │ │ └── services │ │ │ │ │ ├── device-auth.service.ts │ │ │ │ │ ├── devices.service.ts │ │ │ │ │ ├── docker-device.service.ts │ │ │ │ │ ├── proxmox-device.service.ts │ │ │ │ │ └── sensitive-info.service.ts │ │ │ ├── devices.module.ts │ │ │ ├── domain │ │ │ │ ├── entities │ │ │ │ │ ├── device-auth.entity.ts │ │ │ │ │ └── device.entity.ts │ │ │ │ ├── interfaces │ │ │ │ │ └── devices-service.interface.ts │ │ │ │ ├── repositories │ │ │ │ │ ├── device-auth-repository.interface.ts │ │ │ │ │ └── device-repository.interface.ts │ │ │ │ └── services │ │ │ │ │ ├── device-auth-service.interface.ts │ │ │ │ │ ├── devices-service.interface.ts │ │ │ │ │ ├── docker-device-service.interface.ts │ │ │ │ │ ├── proxmox-device-service.interface.ts │ │ │ │ │ └── sensitive-info.service.interface.ts │ │ │ ├── index.ts │ │ │ ├── infrastructure │ │ │ │ ├── mappers │ │ │ │ │ └── device-repository.mapper.ts │ │ │ │ ├── repositories │ │ │ │ │ ├── device-auth.repository.ts │ │ │ │ │ └── device.repository.ts │ │ │ │ └── schemas │ │ │ │ │ ├── device-auth.schema.ts │ │ │ │ │ └── device.schema.ts │ │ │ └── presentation │ │ │ │ ├── controllers │ │ │ │ ├── devices-auth.controller.ts │ │ │ │ ├── devices-capabilities.controller.ts │ │ │ │ ├── devices-configuration.controller.ts │ │ │ │ ├── devices-microservice.controller.ts │ │ │ │ └── devices.controller.ts │ │ │ │ ├── decorators │ │ │ │ ├── devices-auth.decorators.ts │ │ │ │ ├── devices-capabilities.decorators.ts │ │ │ │ ├── devices-configuration.decorators.ts │ │ │ │ └── devices.decorators.ts │ │ │ │ ├── dtos │ │ │ │ ├── device-auth-response.dto.ts │ │ │ │ ├── device-auth.dto.ts │ │ │ │ ├── device-capabilities.dto.ts │ │ │ │ ├── device-configuration.dto.ts │ │ │ │ ├── device.dto.ts │ │ │ │ ├── update-docker-auth.dto.ts │ │ │ │ └── update-proxmox-auth.dto.ts │ │ │ │ └── mappers │ │ │ │ └── device.mapper.ts │ │ ├── diagnostic │ │ │ ├── README.md │ │ │ ├── __tests__ │ │ │ │ ├── application │ │ │ │ │ └── services │ │ │ │ │ │ ├── diagnostic.service.spec.ts │ │ │ │ │ │ └── test-setup.ts │ │ │ │ ├── controllers │ │ │ │ │ └── diagnostic.controller.spec.ts │ │ │ │ ├── infrastructure │ │ │ │ │ └── repositories │ │ │ │ │ │ ├── diagnostic.repository.spec.ts │ │ │ │ │ │ └── test-setup.ts │ │ │ │ └── presentation │ │ │ │ │ ├── controllers │ │ │ │ │ ├── diagnostic.controller.spec.ts │ │ │ │ │ └── test-setup.ts │ │ │ │ │ ├── gateways │ │ │ │ │ └── diagnostic.gateway.spec.ts │ │ │ │ │ └── mappers │ │ │ │ │ └── diagnostic.mapper.spec.ts │ │ │ ├── application │ │ │ │ └── services │ │ │ │ │ └── diagnostic.service.ts │ │ │ ├── diagnostic.module.ts │ │ │ ├── domain │ │ │ │ ├── entities │ │ │ │ │ └── diagnostic.entity.ts │ │ │ │ └── interfaces │ │ │ │ │ └── diagnostic-service.interface.ts │ │ │ ├── index.ts │ │ │ └── presentation │ │ │ │ ├── controllers │ │ │ │ └── diagnostic.controller.ts │ │ │ │ ├── decorators │ │ │ │ └── diagnostic.decorators.ts │ │ │ │ ├── dtos │ │ │ │ └── diagnostic.dto.ts │ │ │ │ ├── gateways │ │ │ │ ├── diagnostic-events.gateway.ts │ │ │ │ └── diagnostic.gateway.ts │ │ │ │ └── mappers │ │ │ │ └── diagnostic.mapper.ts │ │ ├── health │ │ │ ├── README.md │ │ │ ├── decorators │ │ │ │ └── health.decorators.ts │ │ │ ├── health.controller.ts │ │ │ ├── health.module.ts │ │ │ └── presentation │ │ │ │ └── dtos │ │ │ │ └── health.dto.ts │ │ ├── logs │ │ │ ├── README.md │ │ │ ├── __tests__ │ │ │ │ ├── application │ │ │ │ │ └── services │ │ │ │ │ │ └── server-logs.service.spec.ts │ │ │ │ ├── infrastructure │ │ │ │ │ └── repositories │ │ │ │ │ │ ├── ansible-logs.repository.spec.ts │ │ │ │ │ │ ├── ansible-task.repository.spec.ts │ │ │ │ │ │ ├── server-logs.repository.spec.ts │ │ │ │ │ │ └── test-setup.ts │ │ │ │ ├── presentation │ │ │ │ │ └── controllers │ │ │ │ │ │ └── logs.controller.spec.ts │ │ │ │ └── test-setup.ts │ │ │ ├── application │ │ │ │ └── services │ │ │ │ │ ├── ansible-logs.service.ts │ │ │ │ │ └── server-logs.service.ts │ │ │ ├── domain │ │ │ │ ├── entities │ │ │ │ │ ├── ansible-log.entity.ts │ │ │ │ │ └── server-log.entity.ts │ │ │ │ ├── interfaces │ │ │ │ │ ├── ansible-logs-service.interface.ts │ │ │ │ │ └── server-logs-service.interface.ts │ │ │ │ └── repositories │ │ │ │ │ ├── ansible-logs-repository.interface.ts │ │ │ │ │ └── server-logs-repository.interface.ts │ │ │ ├── index.ts │ │ │ ├── infrastructure │ │ │ │ ├── mappers │ │ │ │ │ ├── ansible-log.mapper.ts │ │ │ │ │ └── server-log.mapper.ts │ │ │ │ ├── repositories │ │ │ │ │ ├── ansible-logs.repository.ts │ │ │ │ │ └── server-logs.repository.ts │ │ │ │ └── schemas │ │ │ │ │ ├── ansible-log.schema.ts │ │ │ │ │ └── server-log.schema.ts │ │ │ ├── logs.module.ts │ │ │ └── presentation │ │ │ │ ├── controllers │ │ │ │ └── logs.controller.ts │ │ │ │ ├── dtos │ │ │ │ ├── server-log-response.dto.ts │ │ │ │ └── server-logs-query.dto.ts │ │ │ │ └── mappers │ │ │ │ └── server-log.mapper.ts │ │ ├── mcp │ │ │ ├── README.md │ │ │ ├── application │ │ │ │ ├── constants │ │ │ │ │ └── mcp.constants.ts │ │ │ │ ├── dto │ │ │ │ │ ├── container-action.payload.dto.ts │ │ │ │ │ ├── device.response.dto.ts │ │ │ │ │ ├── execute-playbook.payload.dto.ts │ │ │ │ │ ├── get-container.payload.dto.ts │ │ │ │ │ ├── get-containers.payload.dto.ts │ │ │ │ │ ├── get-device.payload.dto.ts │ │ │ │ │ ├── get-devices.payload.dto.ts │ │ │ │ │ ├── get-stats-query.payload.dto.ts │ │ │ │ │ ├── playbook-status.payload.dto.ts │ │ │ │ │ └── timeseries-stats.response.dto.ts │ │ │ │ └── services │ │ │ │ │ ├── mcp-handler-registry.service.ts │ │ │ │ │ └── mcp-notification.service.ts │ │ │ ├── infrastructure │ │ │ │ ├── handlers │ │ │ │ │ ├── container.handler.ts │ │ │ │ │ ├── device.handler.ts │ │ │ │ │ ├── echo.handler.ts │ │ │ │ │ ├── playbook.handler.ts │ │ │ │ │ └── stats.handler.ts │ │ │ │ └── transport │ │ │ │ │ └── mcp-transport.service.ts │ │ │ ├── mcp.module.ts │ │ │ └── presentation │ │ │ │ ├── controllers │ │ │ │ └── mcp-settings.controller.ts │ │ │ │ ├── decorators │ │ │ │ └── mcp-settings.decorators.ts │ │ │ │ └── dtos │ │ │ │ └── mcp-settings.dto.ts │ │ ├── notifications │ │ │ ├── README.md │ │ │ ├── __tests__ │ │ │ │ ├── application │ │ │ │ │ └── services │ │ │ │ │ │ └── notification.service.spec.ts │ │ │ │ ├── infrastructure │ │ │ │ │ └── repositories │ │ │ │ │ │ └── notification.repository.spec.ts │ │ │ │ └── presentation │ │ │ │ │ └── controllers │ │ │ │ │ └── notification.controller.spec.ts │ │ │ ├── application │ │ │ │ └── services │ │ │ │ │ ├── notification-component.service.ts │ │ │ │ │ └── notification.service.ts │ │ │ ├── domain │ │ │ │ ├── entities │ │ │ │ │ └── notification.entity.ts │ │ │ │ ├── interfaces │ │ │ │ │ ├── notification-component-service.interface.ts │ │ │ │ │ └── notification-service.interface.ts │ │ │ │ └── repositories │ │ │ │ │ └── notification-repository.interface.ts │ │ │ ├── index.ts │ │ │ ├── infrastructure │ │ │ │ ├── repositories │ │ │ │ │ └── notification.repository.ts │ │ │ │ └── schemas │ │ │ │ │ └── notification.schema.ts │ │ │ ├── notifications.module.ts │ │ │ └── presentation │ │ │ │ ├── controllers │ │ │ │ └── notification.controller.ts │ │ │ │ ├── decorators │ │ │ │ └── notification.decorators.ts │ │ │ │ └── gateways │ │ │ │ └── notifications.gateway.ts │ │ ├── playbooks │ │ │ ├── README.md │ │ │ ├── __tests__ │ │ │ │ ├── application │ │ │ │ │ └── services │ │ │ │ │ │ ├── components │ │ │ │ │ │ ├── abstract-playbooks-register-test-setup.ts │ │ │ │ │ │ ├── abstract-playbooks-register.component.spec.ts │ │ │ │ │ │ ├── component-factory-test-setup.ts │ │ │ │ │ │ ├── component-factory.service.spec.ts │ │ │ │ │ │ ├── git-playbooks-register-test-setup.ts │ │ │ │ │ │ ├── git-playbooks-register.component.spec.ts │ │ │ │ │ │ ├── local-playbooks-repository-test-setup.ts │ │ │ │ │ │ └── local-playbooks-repository.component.spec.ts │ │ │ │ │ │ ├── default-playbooks-register-test-setup.ts │ │ │ │ │ │ ├── default-playbooks-register.service.spec.ts │ │ │ │ │ │ ├── engine │ │ │ │ │ │ ├── playbooks-register-engine-test-setup.ts │ │ │ │ │ │ └── playbooks-register-engine.service.spec.ts │ │ │ │ │ │ ├── playbook.service.spec.ts │ │ │ │ │ │ ├── playbooks-register-test-setup.ts │ │ │ │ │ │ ├── playbooks-register.service.spec.ts │ │ │ │ │ │ └── test-setup.ts │ │ │ │ ├── domain │ │ │ │ │ └── entities │ │ │ │ │ │ └── playbooks-register.entity.spec.ts │ │ │ │ ├── infrastructure │ │ │ │ │ └── repositories │ │ │ │ │ │ ├── playbook.repository.spec.ts │ │ │ │ │ │ └── playbooks-register.repository.spec.ts │ │ │ │ ├── playbooks.module.spec.ts │ │ │ │ ├── presentation │ │ │ │ │ └── controllers │ │ │ │ │ │ ├── git-playbooks-register-test-setup.ts │ │ │ │ │ │ ├── git-playbooks-register.controller.spec.ts │ │ │ │ │ │ ├── local-playbooks-register-test-setup.ts │ │ │ │ │ │ ├── local-playbooks-register.controller.spec.ts │ │ │ │ │ │ ├── playbook.controller.spec.ts │ │ │ │ │ │ ├── playbooks-repository-test-setup.ts │ │ │ │ │ │ ├── playbooks-repository.controller.spec.ts │ │ │ │ │ │ └── test-setup.ts │ │ │ │ ├── test-setup.ts │ │ │ │ └── utils │ │ │ │ │ └── tree-utils.spec.ts │ │ │ ├── application │ │ │ │ └── services │ │ │ │ │ ├── components │ │ │ │ │ ├── abstract-playbooks-register.component.ts │ │ │ │ │ ├── component-factory.service.ts │ │ │ │ │ ├── git-playbooks-register.component.ts │ │ │ │ │ └── local-playbooks-repository.component.ts │ │ │ │ │ ├── default-playbooks-register.service.ts │ │ │ │ │ ├── engine │ │ │ │ │ └── playbooks-register-engine.service.ts │ │ │ │ │ ├── playbook.service.ts │ │ │ │ │ ├── playbooks-register.service.ts │ │ │ │ │ ├── register-tree.service.ts │ │ │ │ │ └── tree-node.service.ts │ │ │ ├── constants.ts │ │ │ ├── domain │ │ │ │ ├── entities │ │ │ │ │ ├── playbook.entity.ts │ │ │ │ │ └── playbooks-register.entity.ts │ │ │ │ ├── interfaces │ │ │ │ │ ├── component-options.interface.ts │ │ │ │ │ ├── playbooks-register-component-factory.interface.ts │ │ │ │ │ ├── playbooks-register-component.interface.ts │ │ │ │ │ ├── playbooks-register-engine-service.interface.ts │ │ │ │ │ ├── playbooks-service.interface.ts │ │ │ │ │ └── tree-node-service.interface.ts │ │ │ │ ├── repositories │ │ │ │ │ ├── playbook-repository.interface.ts │ │ │ │ │ └── playbooks-register-repository.interface.ts │ │ │ │ └── services │ │ │ │ │ └── playbooks-register-service.interface.ts │ │ │ ├── index.ts │ │ │ ├── infrastructure │ │ │ │ ├── mappers │ │ │ │ │ └── playbook.mapper.ts │ │ │ │ ├── repositories │ │ │ │ │ ├── playbook.repository.ts │ │ │ │ │ └── playbooks-register.repository.ts │ │ │ │ └── schemas │ │ │ │ │ ├── playbook.schema.ts │ │ │ │ │ └── playbooks-register.schema.ts │ │ │ ├── playbooks.module.ts │ │ │ └── presentation │ │ │ │ ├── controllers │ │ │ │ ├── git-playbooks-register.controller.ts │ │ │ │ ├── local-playbooks-register.controller.ts │ │ │ │ ├── playbooks-diagnostic.controller.ts │ │ │ │ ├── playbooks-microservice.controller.ts │ │ │ │ ├── playbooks-repository.controller.ts │ │ │ │ └── playbooks.controller.ts │ │ │ │ ├── decorators │ │ │ │ ├── git-repository.decorators.ts │ │ │ │ ├── local-playbooks-repository.decorators.ts │ │ │ │ ├── playbook-diagnostic.decorators.ts │ │ │ │ ├── playbook.decorators.ts │ │ │ │ └── playbooks-repository.decorators.ts │ │ │ │ └── dtos │ │ │ │ ├── git-repository.dto.ts │ │ │ │ ├── local-repository.dto.ts │ │ │ │ ├── playbook-execution.dto.ts │ │ │ │ ├── playbook-extra-var.dto.ts │ │ │ │ ├── playbook.dto.ts │ │ │ │ └── pre-check-device-connection.dto.ts │ │ ├── remote-system-information │ │ │ ├── README.md │ │ │ ├── __tests__ │ │ │ │ └── application │ │ │ │ │ └── services │ │ │ │ │ └── remote-system-information.service.spec.ts │ │ │ ├── application │ │ │ │ └── services │ │ │ │ │ ├── components │ │ │ │ │ ├── core │ │ │ │ │ │ └── base-component.ts │ │ │ │ │ └── watchers │ │ │ │ │ │ └── remote-system-information-watcher.ts │ │ │ │ │ ├── engine │ │ │ │ │ └── remote-system-information-engine.service.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── remote-ssh-executor.service.ts │ │ │ │ │ └── remote-system-information.service.ts │ │ │ ├── domain │ │ │ │ ├── helpers │ │ │ │ │ └── sudo.ts │ │ │ │ ├── index.ts │ │ │ │ ├── interfaces │ │ │ │ │ ├── component.interface.ts │ │ │ │ │ ├── remote-ssh-executor-service.interface.ts │ │ │ │ │ ├── remote-ssh-executor.interface.ts │ │ │ │ │ ├── remote-system-information-engine-service.interface.ts │ │ │ │ │ ├── remote-system-information-service.interface.ts │ │ │ │ │ └── system-information-component.interface.ts │ │ │ │ ├── system-information │ │ │ │ │ ├── bluetooth │ │ │ │ │ │ ├── BluetoothComponent.ts │ │ │ │ │ │ ├── bluetooth.consts.ts │ │ │ │ │ │ └── bluetooth.utils.ts │ │ │ │ │ ├── constants │ │ │ │ │ │ └── raspberry.constants.ts │ │ │ │ │ ├── cpu │ │ │ │ │ │ ├── cpu.component.ts │ │ │ │ │ │ ├── cpu.consts.ts │ │ │ │ │ │ └── cpu.utils.ts │ │ │ │ │ ├── filesystem │ │ │ │ │ │ ├── FileSystemComponent.ts │ │ │ │ │ │ ├── filesystem.consts.ts │ │ │ │ │ │ └── filesystem.utils.ts │ │ │ │ │ ├── graphics │ │ │ │ │ │ ├── GraphicsComponent.ts │ │ │ │ │ │ ├── graphics.consts.ts │ │ │ │ │ │ └── graphics.utils.ts │ │ │ │ │ ├── memory │ │ │ │ │ │ ├── MemoryComponent.ts │ │ │ │ │ │ ├── memory.consts.ts │ │ │ │ │ │ └── memory.utils.ts │ │ │ │ │ ├── network │ │ │ │ │ │ ├── NetworkComponent.ts │ │ │ │ │ │ └── networks.utils.ts │ │ │ │ │ ├── os-information │ │ │ │ │ │ ├── OSInformationComponent.ts │ │ │ │ │ │ └── osinformation.utils.ts │ │ │ │ │ ├── remote-os │ │ │ │ │ │ ├── remote-os.component.ts │ │ │ │ │ │ └── remoteos.utils.ts │ │ │ │ │ ├── system │ │ │ │ │ │ ├── SystemComponent.ts │ │ │ │ │ │ ├── system.consts.ts │ │ │ │ │ │ └── system.utils.ts │ │ │ │ │ ├── types.d.ts │ │ │ │ │ ├── usb │ │ │ │ │ │ ├── USBComponent.ts │ │ │ │ │ │ └── usb.utils.ts │ │ │ │ │ ├── users │ │ │ │ │ │ ├── UsersComponent.ts │ │ │ │ │ │ └── users.utils.ts │ │ │ │ │ ├── utils │ │ │ │ │ │ └── system-utils.ts │ │ │ │ │ └── wifi │ │ │ │ │ │ ├── WifiComponent.ts │ │ │ │ │ │ ├── wifi.consts.ts │ │ │ │ │ │ └── wifi.utils.ts │ │ │ │ └── types │ │ │ │ │ ├── configuration.types.ts │ │ │ │ │ ├── remote-executor.types.ts │ │ │ │ │ └── update.types.ts │ │ │ ├── index.ts │ │ │ ├── infrastructure │ │ │ │ ├── queue │ │ │ │ │ ├── constants.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── remote-system-information.processor.ts │ │ │ │ │ └── types.ts │ │ │ │ └── websockets │ │ │ │ │ └── remote-system-information-debug.gateway.ts │ │ │ ├── presentation │ │ │ │ ├── controllers │ │ │ │ │ └── diagnostic.ts │ │ │ │ └── dtos │ │ │ │ │ └── pre-check-remote-system-information.dto.ts │ │ │ └── remote-system-information.module.ts │ │ ├── scheduler │ │ │ ├── README.md │ │ │ ├── __tests__ │ │ │ │ ├── application │ │ │ │ │ └── services │ │ │ │ │ │ ├── cron.service.spec.ts │ │ │ │ │ │ └── system-cron.service.spec.ts │ │ │ │ ├── infrastructure │ │ │ │ │ ├── mappers │ │ │ │ │ │ └── cron-repository.mapper.spec.ts │ │ │ │ │ └── repositories │ │ │ │ │ │ └── cron.repository.spec.ts │ │ │ │ └── presentation │ │ │ │ │ └── controllers │ │ │ │ │ └── cron.controller.spec.ts │ │ │ ├── application │ │ │ │ └── services │ │ │ │ │ ├── cron.service.ts │ │ │ │ │ └── system-cron.service.ts │ │ │ ├── domain │ │ │ │ ├── entities │ │ │ │ │ └── cron.entity.ts │ │ │ │ ├── interfaces │ │ │ │ │ ├── cron-service.interface.ts │ │ │ │ │ └── system-cron-service.interface.ts │ │ │ │ └── repositories │ │ │ │ │ └── cron-repository.interface.ts │ │ │ ├── infrastructure │ │ │ │ ├── mappers │ │ │ │ │ └── cron-repository.mapper.ts │ │ │ │ ├── repositories │ │ │ │ │ └── cron.repository.ts │ │ │ │ └── schemas │ │ │ │ │ └── cron.schema.ts │ │ │ ├── presentation │ │ │ │ ├── controllers │ │ │ │ │ └── cron.controller.ts │ │ │ │ ├── dto │ │ │ │ │ └── cron.dto.ts │ │ │ │ └── dtos │ │ │ │ │ └── get-cron.dto.ts │ │ │ └── scheduler.module.ts │ │ ├── settings │ │ │ ├── README.md │ │ │ ├── __tests__ │ │ │ │ ├── advanced-operations.service.spec.ts │ │ │ │ ├── information.service.spec.ts │ │ │ │ ├── settings.controller.spec.ts │ │ │ │ └── settings.service.spec.ts │ │ │ ├── application │ │ │ │ └── services │ │ │ │ │ ├── advanced-operations.service.ts │ │ │ │ │ ├── information.service.ts │ │ │ │ │ └── settings.service.ts │ │ │ ├── domain │ │ │ │ ├── entities │ │ │ │ │ └── setting.entity.ts │ │ │ │ ├── interfaces │ │ │ │ │ ├── advanced-operations-service.interface.ts │ │ │ │ │ ├── information-service.interface.ts │ │ │ │ │ └── settings-service.interface.ts │ │ │ │ └── repositories │ │ │ │ │ └── setting-repository.interface.ts │ │ │ ├── index.ts │ │ │ ├── infrastructure │ │ │ │ ├── interfaces │ │ │ │ │ └── settings-migration-service.interface.ts │ │ │ │ └── repositories │ │ │ │ │ └── setting.repository.ts │ │ │ ├── presentation │ │ │ │ ├── controllers │ │ │ │ │ └── settings.controller.ts │ │ │ │ ├── decorators │ │ │ │ │ └── settings.decorators.ts │ │ │ │ ├── dto │ │ │ │ │ └── setting.dto.ts │ │ │ │ ├── dtos │ │ │ │ │ ├── stats.dto.ts │ │ │ │ │ └── update-setting.dto.ts │ │ │ │ └── validators │ │ │ │ │ ├── dashboard.validator.ts │ │ │ │ │ ├── device-stats.validator.ts │ │ │ │ │ ├── devices.validator.ts │ │ │ │ │ ├── logs.validator.ts │ │ │ │ │ └── master-node-url.validator.ts │ │ │ └── settings.module.ts │ │ ├── sftp │ │ │ ├── README.md │ │ │ ├── __tests__ │ │ │ │ ├── application │ │ │ │ │ └── sftp.service.spec.ts │ │ │ │ ├── dto │ │ │ │ │ └── sftp-session.dto.ts │ │ │ │ ├── infrastructure │ │ │ │ │ ├── mock-sftp.repository.ts │ │ │ │ │ └── sftp.repository.spec.ts │ │ │ │ ├── presentation │ │ │ │ │ └── sftp.gateway.spec.ts │ │ │ │ ├── test-setup.fixed.ts │ │ │ │ └── test-setup.ts │ │ │ ├── application │ │ │ │ └── services │ │ │ │ │ └── sftp.service.ts │ │ │ ├── domain │ │ │ │ ├── entities │ │ │ │ │ └── sftp.entity.ts │ │ │ │ ├── interfaces │ │ │ │ │ └── sftp-service.interface.ts │ │ │ │ └── repositories │ │ │ │ │ └── sftp-repository.interface.ts │ │ │ ├── index.ts │ │ │ ├── infrastructure │ │ │ │ ├── repositories │ │ │ │ │ └── sftp.repository.ts │ │ │ │ └── services │ │ │ │ │ └── file-stream.service.ts │ │ │ ├── presentation │ │ │ │ ├── dtos │ │ │ │ │ └── sftp-session.dto.ts │ │ │ │ └── gateways │ │ │ │ │ └── sftp.gateway.ts │ │ │ └── sftp.module.ts │ │ ├── shell │ │ │ ├── README.md │ │ │ ├── __tests__ │ │ │ │ ├── application │ │ │ │ │ └── services │ │ │ │ │ │ ├── docker-compose.service.spec.ts │ │ │ │ │ │ ├── file-system.service.spec.ts │ │ │ │ │ │ ├── playbook-file.service.spec.ts │ │ │ │ │ │ ├── shell-wrapper.service.spec.ts │ │ │ │ │ │ └── ssh-key.service.spec.ts │ │ │ │ ├── infrastructure │ │ │ │ │ └── shell-wrapper.spec.ts │ │ │ │ └── vitest.config.js │ │ │ ├── application │ │ │ │ └── services │ │ │ │ │ ├── docker-compose.service.ts │ │ │ │ │ ├── file-system.service.ts │ │ │ │ │ ├── playbook-file.service.ts │ │ │ │ │ ├── shell-wrapper.service.ts │ │ │ │ │ └── ssh-key.service.ts │ │ │ ├── domain │ │ │ │ ├── entities │ │ │ │ │ └── shell-command.entity.ts │ │ │ │ └── interfaces │ │ │ │ │ ├── docker-compose.interface.ts │ │ │ │ │ ├── file-system.interface.ts │ │ │ │ │ ├── playbook-file.interface.ts │ │ │ │ │ ├── shell-wrapper.interface.ts │ │ │ │ │ └── ssh-key.interface.ts │ │ │ ├── index.ts │ │ │ ├── infrastructure │ │ │ │ └── shell-wrapper.ts │ │ │ └── shell.module.ts │ │ ├── smart-failure │ │ │ ├── README.md │ │ │ ├── __tests__ │ │ │ │ ├── application │ │ │ │ │ └── services │ │ │ │ │ │ └── smart-failure.service.spec.ts │ │ │ │ ├── infrastructure │ │ │ │ │ └── repositories │ │ │ │ │ │ └── ansible-logs.repository.spec.ts │ │ │ │ └── presentation │ │ │ │ │ └── controllers │ │ │ │ │ ├── smart-failure.controller.spec.ts │ │ │ │ │ └── smart-failure.enhanced.spec.ts │ │ │ ├── application │ │ │ │ └── services │ │ │ │ │ └── smart-failure.service.ts │ │ │ ├── domain │ │ │ │ ├── constants.ts │ │ │ │ ├── entities │ │ │ │ │ ├── failure-pattern.entity.ts │ │ │ │ │ └── failure-pattern.interface.ts │ │ │ │ ├── interfaces │ │ │ │ │ └── smart-failure.service.interface.ts │ │ │ │ └── repositories │ │ │ │ │ └── smart-failure.repository.interface.ts │ │ │ ├── index.ts │ │ │ ├── infrastructure │ │ │ │ └── repositories │ │ │ │ │ └── smart-failure.repository.ts │ │ │ ├── presentation │ │ │ │ ├── controllers │ │ │ │ │ └── smart-failure.controller.ts │ │ │ │ ├── decorators │ │ │ │ │ └── smart-failure.decorators.ts │ │ │ │ └── dtos │ │ │ │ │ └── smart-failure.dto.ts │ │ │ └── smart-failure.module.ts │ │ ├── ssh │ │ │ ├── README.md │ │ │ ├── __tests__ │ │ │ │ ├── application │ │ │ │ │ ├── ssh-connection.service.spec.ts │ │ │ │ │ └── ssh-terminal.service.spec.ts │ │ │ │ ├── presentation │ │ │ │ │ └── ssh.gateway.spec.ts │ │ │ │ └── test-setup.ts │ │ │ ├── application │ │ │ │ └── services │ │ │ │ │ └── ssh-terminal.service.ts │ │ │ ├── domain │ │ │ │ ├── entities │ │ │ │ │ └── ssh.entity.ts │ │ │ │ ├── interfaces │ │ │ │ │ ├── ssh-connection-service.interface.ts │ │ │ │ │ ├── ssh-gateway-service.interface.ts │ │ │ │ │ └── ssh-terminal-service.interface.ts │ │ │ │ └── repositories │ │ │ │ │ └── ssh-session-repository.interface.ts │ │ │ ├── index.ts │ │ │ ├── presentation │ │ │ │ ├── dtos │ │ │ │ │ └── ssh-session.dto.ts │ │ │ │ └── gateways │ │ │ │ │ └── ssh.gateway.ts │ │ │ └── ssh.module.ts │ │ ├── statistics │ │ │ ├── README.md │ │ │ ├── __tests__ │ │ │ │ ├── application │ │ │ │ │ └── services │ │ │ │ │ │ ├── device-downtime.service.spec.ts │ │ │ │ │ │ └── metrics.service.spec.ts │ │ │ │ ├── controllers │ │ │ │ │ ├── dashboard.controller.spec.ts │ │ │ │ │ ├── device-stats-controller-test-setup.ts │ │ │ │ │ └── device-stats.controller.spec.ts │ │ │ │ ├── infrastructure │ │ │ │ │ ├── mappers │ │ │ │ │ │ └── device-downtime-event-repository.mapper.spec.ts │ │ │ │ │ └── repositories │ │ │ │ │ │ └── device-downtime-event.repository.spec.ts │ │ │ │ ├── presentation │ │ │ │ │ └── controllers │ │ │ │ │ │ ├── metrics.controller.spec.ts │ │ │ │ │ │ └── statistics-microservice.controller.spec.ts │ │ │ │ ├── services │ │ │ │ │ ├── dashboard.service.spec.ts │ │ │ │ │ ├── device-stats-service-test-setup.ts │ │ │ │ │ └── device-stats.service.spec.ts │ │ │ │ └── test-setup.ts │ │ │ ├── application │ │ │ │ └── services │ │ │ │ │ ├── dashboard.service.ts │ │ │ │ │ ├── device-downtime.service.ts │ │ │ │ │ ├── device-stats.service.ts │ │ │ │ │ └── metrics.service.ts │ │ │ ├── domain │ │ │ │ ├── constants │ │ │ │ │ └── constants.ts │ │ │ │ ├── entities │ │ │ │ │ └── device-downtime-event.entity.ts │ │ │ │ ├── interfaces │ │ │ │ │ ├── dashboard-service.interface.ts │ │ │ │ │ ├── device-downtime-service.interface.ts │ │ │ │ │ ├── device-stats-service.interface.ts │ │ │ │ │ └── metrics-service.interface.ts │ │ │ │ └── repositories │ │ │ │ │ └── device-downtime-event-repository.interface.ts │ │ │ ├── index.ts │ │ │ ├── infrastructure │ │ │ │ ├── mappers │ │ │ │ │ └── device-downtime-event-repository.mapper.ts │ │ │ │ ├── repositories │ │ │ │ │ └── device-downtime-event.repository.ts │ │ │ │ └── schemas │ │ │ │ │ └── device-downtime-event.schema.ts │ │ │ ├── presentation │ │ │ │ ├── controllers │ │ │ │ │ ├── dashboard.controller.ts │ │ │ │ │ ├── device-stats.controller.ts │ │ │ │ │ ├── metrics.controller.ts │ │ │ │ │ └── statistics-microservice.controller.ts │ │ │ │ ├── decorators │ │ │ │ │ ├── dashboard.decorators.ts │ │ │ │ │ └── metrics.decorators.ts │ │ │ │ ├── dto │ │ │ │ │ ├── dashboard-stats.dto.ts │ │ │ │ │ └── device-stats.dto.ts │ │ │ │ └── dtos │ │ │ │ │ └── get-dashboard-stats.dto.ts │ │ │ └── statistics.module.ts │ │ ├── telemetry │ │ │ ├── README.md │ │ │ ├── __tests__ │ │ │ │ ├── fixed-telemetry.module.spec.ts │ │ │ │ ├── fixed-telemetry.service.spec.ts │ │ │ │ ├── simple-module.spec.ts │ │ │ │ ├── simple-telemetry.service.spec.ts │ │ │ │ ├── telemetry-service-spy.fixed.spec.ts │ │ │ │ ├── telemetry-service-spy.spec.ts │ │ │ │ ├── telemetry.integration.basic.spec.ts │ │ │ │ ├── telemetry.integration.fixed.spec.ts │ │ │ │ ├── telemetry.integration.spec.ts │ │ │ │ ├── telemetry.mock.spec.ts │ │ │ │ ├── telemetry.module.fixed.spec.ts │ │ │ │ ├── telemetry.module.spec.ts │ │ │ │ ├── telemetry.network-error.spec.ts │ │ │ │ ├── telemetry.service.basic.spec.ts │ │ │ │ ├── telemetry.service.comprehensive.spec.ts │ │ │ │ ├── telemetry.service.fixed.spec.ts │ │ │ │ ├── telemetry.service.mock.spec.ts │ │ │ │ └── telemetry.service.spec.ts │ │ │ ├── dto │ │ │ │ └── telemetry-event-payload.dto.ts │ │ │ ├── index.ts │ │ │ ├── telemetry.module.ts │ │ │ └── telemetry.service.ts │ │ ├── update │ │ │ ├── README.md │ │ │ ├── __tests__ │ │ │ │ └── services │ │ │ │ │ └── update.service.spec.ts │ │ │ ├── domain │ │ │ │ └── interfaces │ │ │ │ │ └── update-service.interface.ts │ │ │ ├── index.ts │ │ │ ├── services │ │ │ │ └── update.service.ts │ │ │ └── update.module.ts │ │ └── users │ │ │ ├── README.md │ │ │ ├── __tests__ │ │ │ ├── application │ │ │ │ └── services │ │ │ │ │ └── users.service.spec.ts │ │ │ ├── presentation │ │ │ │ └── controllers │ │ │ │ │ ├── users-controller-test-setup.ts │ │ │ │ │ └── users.controller.spec.ts │ │ │ └── test-setup.ts │ │ │ ├── application │ │ │ └── services │ │ │ │ └── users.service.ts │ │ │ ├── domain │ │ │ ├── entities │ │ │ │ └── user.entity.ts │ │ │ ├── interfaces │ │ │ │ └── users-service.interface.ts │ │ │ └── repositories │ │ │ │ └── user-repository.interface.ts │ │ │ ├── index.ts │ │ │ ├── infrastructure │ │ │ ├── mappers │ │ │ │ └── user-repository.mapper.ts │ │ │ ├── repositories │ │ │ │ └── user.repository.ts │ │ │ └── schemas │ │ │ │ └── user.schema.ts │ │ │ ├── presentation │ │ │ ├── controllers │ │ │ │ └── users.controller.ts │ │ │ ├── decorators │ │ │ │ └── users.decorators.ts │ │ │ ├── dtos │ │ │ │ ├── login-response.dto.ts │ │ │ │ └── login.dto.ts │ │ │ └── mappers │ │ │ │ └── user.mapper.ts │ │ │ └── users.module.ts │ ├── tests │ │ └── molecule │ │ │ ├── README.md │ │ │ ├── create-docker-network │ │ │ ├── converge.yml │ │ │ ├── molecule.yml │ │ │ ├── prepare.yml │ │ │ └── verify.yml │ │ │ ├── default │ │ │ ├── molecule.yml │ │ │ └── run_all.yml │ │ │ ├── install-agent-enhanced │ │ │ ├── converge.yml │ │ │ ├── destroy.yml │ │ │ ├── molecule.yml │ │ │ ├── prepare.yml │ │ │ ├── requirements.yml │ │ │ └── verify.yml │ │ │ ├── install-agent │ │ │ ├── converge.yml │ │ │ ├── destroy.yml │ │ │ ├── molecule.yml │ │ │ ├── prepare.yml │ │ │ ├── requirements.yml │ │ │ └── verify.yml │ │ │ ├── install-docker │ │ │ ├── molecule.yml │ │ │ ├── playbook.yml │ │ │ ├── prepare.yml │ │ │ ├── tests │ │ │ │ └── test_default.py │ │ │ └── tools │ │ │ │ └── install-depencencies.sh │ │ │ ├── requirements.txt │ │ │ └── upgrade-packages │ │ │ ├── Dockerfile.j2 │ │ │ ├── converge.yml │ │ │ ├── molecule.yml │ │ │ ├── requirements.yml │ │ │ └── verify.yml │ ├── types │ │ ├── AuthenticatedRequest.d.ts │ │ ├── semver.d.ts │ │ └── typings.d.ts │ └── utils │ │ ├── __tests__ │ │ └── url-validation.spec.ts │ │ └── url-validation.ts ├── tsconfig.build.json ├── tsconfig.json ├── vitest.config.ts └── vitest.workspace.json ├── shared-lib ├── .dockerignore ├── .editorconfig ├── .eslintignore ├── .eslintrc.json ├── .gitignore ├── .prettierignore ├── .prettierrc.json ├── package-lock.json ├── package.json ├── src │ ├── enums │ │ ├── agent.ts │ │ ├── alert.ts │ │ ├── ansible.ts │ │ ├── container.ts │ │ ├── diagnostic.ts │ │ ├── git.ts │ │ ├── proxmox.ts │ │ ├── repositories.ts │ │ ├── settings.ts │ │ ├── stats.ts │ │ └── status.ts │ ├── form │ │ └── automation.ts │ ├── index.ts │ ├── namespace │ │ ├── proxmox.ts │ │ └── system-information.ts │ ├── types │ │ ├── ansible.ts │ │ ├── api.ts │ │ ├── events.ts │ │ └── tree.ts │ └── validation │ │ └── index.ts └── tsconfig.json ├── site ├── .documentation │ └── SVG_STYLE_GUIDE.md ├── .gitignore ├── .vitepress │ ├── config.ts │ └── theme │ │ ├── ComponentDemoLayout.vue │ │ ├── FeatureGuideLayout.vue │ │ ├── custom.css │ │ ├── implementation-guide.css │ │ └── index.js ├── about.md ├── ai.md ├── apps │ └── index.md ├── components │ ├── AdvantagesSection.vue │ ├── CardList.vue │ ├── ComponentInfoCard.vue │ ├── ComponentInfoGrid.vue │ ├── CopyButton.vue │ ├── DecisionNode.vue │ ├── DecisionTree.vue │ ├── DeviceModelDiagram.vue │ ├── Diagram.vue │ ├── FeatureCard.vue │ ├── FeatureGrid.vue │ ├── FeedbackSupportSection.vue │ ├── MentalModelDiagram.vue │ ├── NextStepCard.vue │ ├── PageHeader.vue │ ├── PlatformNote.vue │ ├── PlaybookCodeExample.vue │ ├── PlaybookModelDiagram.vue │ ├── PriorityGrid.vue │ ├── ProcessSteps.vue │ ├── ProcessStepsPlaybook.vue │ ├── RequirementsGrid.vue │ ├── SectionHeader.vue │ ├── StepPath.vue │ ├── SubLinkFeatureCard.vue │ ├── Swiper.vue │ └── TroubleshootingSection.vue ├── docs │ ├── community │ │ ├── contributing.md │ │ ├── index.md │ │ ├── roadmap.md │ │ └── support.md │ ├── concepts │ │ ├── agentless.md │ │ ├── architecture.md │ │ ├── device-model.md │ │ ├── index.md │ │ ├── models │ │ │ ├── automation.md │ │ │ ├── containers.md │ │ │ ├── devices.md │ │ │ ├── playbooks.md │ │ │ └── styles.css │ │ ├── plugins.md │ │ ├── security.md │ │ ├── shared-library.md │ │ └── technologies │ │ │ ├── ansible-integration.md │ │ │ ├── docker-integration.md │ │ │ └── ssh-integration.md │ ├── credits.md │ ├── developer │ │ ├── api-integration.md │ │ ├── development-mode.md │ │ ├── documentation-template.md │ │ ├── index.md │ │ ├── plugins.md │ │ ├── stack.md │ │ └── why-create-a-plugin.md │ ├── getting-started │ │ ├── first-steps.md │ │ ├── index.md │ │ ├── installation.md │ │ ├── installation │ │ │ ├── docker.md │ │ │ ├── dockerless.md │ │ │ ├── proxmox.md │ │ │ ├── proxy-free.md │ │ │ └── update.md │ │ └── requirements.md │ ├── index.md │ ├── reference │ │ ├── ansible │ │ │ ├── api-and-monitoring.md │ │ │ ├── built-in-playbooks.md │ │ │ ├── configuration.md │ │ │ ├── connection-methods.md │ │ │ ├── index.md │ │ │ ├── security.md │ │ │ └── variable-management.md │ │ ├── containers │ │ │ └── labelling.md │ │ ├── docker-configuration.md │ │ ├── docker │ │ │ └── connection.md │ │ ├── environment-variables.md │ │ ├── index.md │ │ ├── installation │ │ │ ├── manual-agent-install.md │ │ │ └── manual-ssm-from-source.md │ │ ├── mongodb-authentication.md │ │ ├── ssh-configuration.md │ │ └── styles.css │ ├── templates │ │ ├── components-demo-template.md │ │ ├── concept-explanation-template.md │ │ └── feature-guide-template.md │ ├── troubleshoot │ │ ├── faq.md │ │ └── index.md │ └── user-guides │ │ ├── automations │ │ ├── creating.md │ │ ├── overview.md │ │ └── schedules.md │ │ ├── containers │ │ ├── deploy-store.md │ │ ├── management.md │ │ └── qemu-lxc-containers.md │ │ ├── devices │ │ ├── adding-devices.md │ │ ├── configuration │ │ │ ├── diagnostic.md │ │ │ ├── docker.md │ │ │ ├── index.md │ │ │ ├── proxmox.md │ │ │ └── ssh.md │ │ ├── index.md │ │ └── management.md │ │ ├── index.md │ │ ├── repositories │ │ ├── local-playbooks.md │ │ └── remote-playbooks.md │ │ ├── settings │ │ ├── mcp.md │ │ ├── overview.md │ │ └── registry.md │ │ └── stacks │ │ ├── containers │ │ ├── editor.md │ │ └── remote-stacks.md │ │ └── playbooks │ │ ├── executing.md │ │ ├── overview.md │ │ └── variables.md ├── index.md ├── netlify.toml ├── package-lock.json ├── package.json ├── public │ ├── cec74183c37dd72ce1e162506a2655ae.txt │ ├── images │ │ ├── 1746729748-add-unmanaged-2.png │ │ ├── about-arrow-roadmap-solid.svg │ │ ├── about-ecosystem.svg │ │ ├── about-goal.svg │ │ ├── about-handshake-outline-rounded.svg │ │ ├── about-simple.gif │ │ ├── about-square-star.svg │ │ ├── about-squarelike.svg │ │ ├── about-squirrel.svg │ │ ├── about-tldraw.svg │ │ ├── acorn.svg │ │ ├── add-device-add-device-1.png │ │ ├── add-device-add-device-2.png │ │ ├── add-device-add-device-3.png │ │ ├── add-device-add-device-4.png │ │ ├── add-device-add-device-5.png │ │ ├── add-device-add-device-6.png │ │ ├── add-device-add-device-7.png │ │ ├── add-unmanaged-1.png │ │ ├── add-unmanaged-2.png │ │ ├── add-unmanaged-3.png │ │ ├── ansible.svg │ │ ├── api-architecture.svg │ │ ├── automations-add-automation.gif │ │ ├── automations-automation-logs.gif │ │ ├── automations-automation-model-diagram.svg │ │ ├── automations-setup-cron.gif │ │ ├── community-roadmap-process.svg │ │ ├── compose-add-remote-options-2.png │ │ ├── compose-compose-1.png │ │ ├── compose-compose-build-1.gif │ │ ├── compose-compose-build-2.png │ │ ├── compose-compose-switch.gif │ │ ├── container-architecture-dark.svg │ │ ├── containers-container-model-diagram.svg │ │ ├── contribution-workflow.svg │ │ ├── delete-device-1.png │ │ ├── device-architecture.svg │ │ ├── device-configuration-device-configuration-1.png │ │ ├── device-configuration-device-configuration-2.png │ │ ├── device-configuration-device-configuration-3.png │ │ ├── device-configuration-device-configuration-4.png │ │ ├── device-configuration-device-configuration-5.png │ │ ├── device-configuration-device-model-diagram.svg │ │ ├── device-configuration-diagnostic-diagnostic-1.png │ │ ├── device-configuration-docker-docker-1.png │ │ ├── device-configuration-proxmox-proxmox-1.png │ │ ├── device-configuration-ssh-advanced-1.png │ │ ├── device-management-device-actions.svg │ │ ├── device-management-device-management-flow.svg │ │ ├── device-management-device-metrics.svg │ │ ├── devices.png │ │ ├── diagrams-concept-diagram.svg │ │ ├── diagrams-container-labelling.svg │ │ ├── diagrams-docker-architecture.svg │ │ ├── diagrams-docker-connection-architecture.svg │ │ ├── exec-playbook-1.png │ │ ├── exec-playbook-2.png │ │ ├── exec-playbook-3.png │ │ ├── exec-playbook-4.png │ │ ├── exec-playbook-5.png │ │ ├── exec-playbook-6.png │ │ ├── first-time-1.png │ │ ├── first-time-2.png │ │ ├── first-time-3.png │ │ ├── flower-twirl.svg │ │ ├── getting-started-feature-highlights.svg │ │ ├── getting-started-onboarding-journey.svg │ │ ├── getting-started-system-architecture.svg │ │ ├── home-advanced-settings.svg │ │ ├── home-container.svg │ │ ├── home-dashboard.png │ │ ├── home-device-info.png │ │ ├── home-devices.png │ │ ├── home-ibm-event-automation.svg │ │ ├── home-integration-general.svg │ │ ├── home-library-filled.svg │ │ ├── home-new-device.png │ │ ├── home-overview.svg │ │ ├── home-playback-speed-bold.svg │ │ ├── home-playbook.png │ │ ├── home-registries.png │ │ ├── home-security.svg │ │ ├── home-services.png │ │ ├── home-stacks.png │ │ ├── home-statistics.svg │ │ ├── home-store.png │ │ ├── install-backup-restore-flow.svg │ │ ├── install-proxmox-install-1.png │ │ ├── install-proxmox-install-2.png │ │ ├── install-proxmox-install-3.png │ │ ├── install-proxmox-install-4.png │ │ ├── install-proxmox-shell.png │ │ ├── install-troubleshooting-update.svg │ │ ├── install-update-process-flow.svg │ │ ├── install-update.png │ │ ├── install-version-compatibility.svg │ │ ├── inventory.png │ │ ├── logo.svg │ │ ├── overview-device-database-encryption-1-solid.svg │ │ ├── overview-hat.svg │ │ ├── overview-magic.svg │ │ ├── overview-reference-architecture.svg │ │ ├── placeholder.png │ │ ├── playbooks-1.png │ │ ├── playbooks-2.png │ │ ├── playbooks-3.png │ │ ├── playbooks-add-file.gif │ │ ├── playbooks-add-local.gif │ │ ├── playbooks-add-remote-options.png │ │ ├── playbooks-add-remote.gif │ │ ├── playbooks-delete-repo.png │ │ ├── playbooks-edit-playbook.gif │ │ ├── playbooks-git.svg │ │ ├── playbooks-local-storage-folder-solid.svg │ │ ├── playbooks-manual-sync.gif │ │ ├── playbooks-playbook-model-diagram.svg │ │ ├── playbooks-playbooks.png │ │ ├── playbooks-remote-dropdown.gif │ │ ├── plugin-architecture.svg │ │ ├── proxmox-install-1.png │ │ ├── proxmox-install-2.png │ │ ├── proxmox-install-3.png │ │ ├── proxmox-install-4.png │ │ ├── proxmox-shell.png │ │ ├── reference-compatibility-matrix.svg │ │ ├── reference-installation-requirements-flow.svg │ │ ├── reference-storage-requirements-dark.svg │ │ ├── reference-storage-requirements.svg │ │ ├── reference-system-requirements.svg │ │ ├── registries-acr-acr.png │ │ ├── registries-acr-acr_01.png │ │ ├── registries-acr-acr_02.png │ │ ├── registries-acr-acr_03.png │ │ ├── registries-custom-custom-1.png │ │ ├── registries-custom-custom-2.png │ │ ├── registries-custom-custom-3.png │ │ ├── registries-ecr-ecr.png │ │ ├── registries-ecr-ecr_01.png │ │ ├── registries-ecr-ecr_02.png │ │ ├── registries-ecr-ecr_03.png │ │ ├── registries-forgejo-forgejo-1.png │ │ ├── registries-forgejo-forgejo-2.png │ │ ├── registries-gcr-gcr.png │ │ ├── registries-ghcr-ghcr.png │ │ ├── registries-ghcr-ghcr_01.png │ │ ├── registries-ghcr-ghcr_02.png │ │ ├── registries-gitea-gitea.png │ │ ├── registries-gitlab-gitlab-1.png │ │ ├── registries-gitlab-gitlab-2.png │ │ ├── registries-gitlab-gitlab_01.png │ │ ├── registries-gitlab-gitlab_02.png │ │ ├── registries-hub-hub-1.png │ │ ├── registries-hub-hub-2.png │ │ ├── registries-hub-hub-3.png │ │ ├── registries-hub-hub_login.png │ │ ├── registries-hub-hub_token.png │ │ ├── registries-lscr-lscr.png │ │ ├── registries-lscr-lscr_01.png │ │ ├── registries-lscr-lscr_02.png │ │ ├── registries-quay-quay.png │ │ ├── registries-quay-quay_01.png │ │ ├── registries-quay-quay_02.png │ │ ├── registries-registries-1.png │ │ ├── registries-registries-2.png │ │ ├── registries-registries-3.png │ │ ├── registries-registries-4.png │ │ ├── registries.png │ │ ├── schema.png │ │ ├── security-model-diagram.svg │ │ ├── services-deploy-conf.png │ │ ├── services-deploy-store.png │ │ ├── services-services-1.png │ │ ├── services-services-2.png │ │ ├── services-services-3.png │ │ ├── services-services-overview.gif │ │ ├── services.png │ │ ├── settings-1.png │ │ ├── settings-2.png │ │ ├── settings-3.png │ │ ├── source-code.svg │ │ ├── squirrel-community.png │ │ ├── squirrel-concepts.png │ │ ├── squirrel-developper.png │ │ ├── squirrel-reference.png │ │ ├── squirrels-cleaned_smooth_fox.svg │ │ ├── squirrels-happy-fox.svg │ │ ├── squirrels-optimized_running_fox.svg │ │ ├── squirrels-squirrel-ai.png │ │ ├── squirrels-squirrel-troubleshoot.png │ │ ├── technical-guide-ansible-ansible-configuration.png │ │ ├── technical-guide-ansible-ansible-configuration.svg │ │ ├── technical-guide-ansible-ansible-connection.svg │ │ ├── technical-guide-ansible-ansible-galaxy.gif │ │ ├── technical-guide-ansible-become-method.png │ │ ├── technical-guide-docker-docker-advanced-connection.png │ │ ├── technical-guide-docker-docker-certs.png │ │ ├── technical-guide-docker-docker-integration-flow.svg │ │ ├── technical-guide-docker-docker-options.png │ │ ├── technical-guide-docker-update-detection-flow.svg │ │ ├── technical-guide-ssh-ssh-connection-flow.svg │ │ ├── technical-guide-ssh-ssh-key.png │ │ ├── technical-guide-ssh-ssh-password.png │ │ ├── technical-guide-troubleshoot-connection-method.png │ │ ├── troubleshooting-common-issues-matrix.svg │ │ ├── troubleshooting-decision-tree-flow.svg │ │ ├── troubleshooting-diagnostic-process.svg │ │ └── troubleshooting-log-locations.svg │ └── logo.svg ├── scripts │ └── check-doc-layouts.cjs ├── team.md └── useful-links.md └── tests ├── mcp ├── global-bundle.pem ├── jest.config.js ├── mcp-client.test.ts ├── package-lock.json ├── package.json └── tsconfig.json └── test-device ├── Dockerfile └── docker-compose.yml /.cursor/rules/front-end.mdc: -------------------------------------------------------------------------------- 1 | --- 2 | description: 3 | globs: *.tsx 4 | alwaysApply: false 5 | --- 6 | 'Use browser_screenshot' when working on frontend files, instead of asking confirmation. -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | # SECRETS 2 | SECRET=REPLACE_ME 3 | SALT=1234567890123456 4 | VAULT_PWD=REPLACE_ME 5 | # MONGO 6 | DB_HOST=mongo 7 | DB_NAME=ssm 8 | DB_PORT=27017 9 | #DB_AUTH_SOURCE= 10 | #DB_USER= 11 | #DB_USER_PWD= 12 | # REDIS 13 | REDIS_HOST=redis 14 | REDIS_PORT=6379 15 | # SSM CONFIG 16 | #SSM_INSTALL_PATH=/opt/squirrelserversmanager 17 | #SSM_DATA_PATH=/data 18 | # TELEMETRY 19 | TELEMETRY_ENABLED=true 20 | # PROMETHEUS 21 | #PROMETHEUS_HOST=http://prometheus:9090 22 | #PROMETHEUS_BASE_URL=/api/v1 23 | PROMETHEUS_USERNAME="user" 24 | PROMETHEUS_PASSWORD="pass" -------------------------------------------------------------------------------- /.env.dev: -------------------------------------------------------------------------------- 1 | # SECRETS 2 | SECRET=REPLACE_ME 3 | SALT=1234567890123456 4 | VAULT_PWD=REPLACE_ME 5 | # MONGO 6 | DB_HOST=mongo 7 | DB_NAME=ssm 8 | DB_PORT=27017 9 | #DB_AUTH_SOURCE= 10 | #DB_USER= 11 | #DB_USER_PWD= 12 | # REDIS 13 | REDIS_HOST=redis 14 | REDIS_PORT=6379 15 | # SSM CONFIG 16 | #SSM_INSTALL_PATH=/opt/squirrelserversmanager 17 | #SSM_DATA_PATH=/data 18 | # TELEMETRY 19 | TELEMETRY_ENABLED=true 20 | # PROMETHEUS 21 | #PROMETHEUS_HOST=http://prometheus:9090 22 | #PROMETHEUS_BASE_URL=/api/v1 23 | PROMETHEUS_USERNAME="user" 24 | PROMETHEUS_PASSWORD="pass" -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "plugins"] 2 | path = plugins 3 | url = https://github.com/SquirrelCorporation/SquirrelServersManager-Plugins 4 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | echo "Running pre-commit checks..." 2 | 3 | # Change to server directory 4 | cd server || exit 1 5 | 6 | # Run build first 7 | echo "Building project..." 8 | npm run build || exit 1 9 | 10 | # Then run tests 11 | echo "Running tests..." 12 | npm test || exit 1 13 | 14 | # If we get here, everything passed 15 | echo "✅ Pre-commit checks passed!" 16 | 17 | # Return to original directory 18 | cd .. 19 | -------------------------------------------------------------------------------- /Dockerfile.koyeb: -------------------------------------------------------------------------------- 1 | FROM koyeb/docker-compose 2 | COPY . /app 3 | RUN rm docker-compose.yml 4 | RUN mv docker-compose.demo.prod.yml docker-compose.yml 5 | -------------------------------------------------------------------------------- /client/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /client/.eslintignore: -------------------------------------------------------------------------------- 1 | /lambda/ 2 | /scripts 3 | /config 4 | .history 5 | public 6 | dist 7 | .umi 8 | mock 9 | server 10 | -------------------------------------------------------------------------------- /client/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /npm-debug.log* 6 | /yarn-error.log 7 | /yarn.lock 8 | 9 | # production 10 | /dist 11 | 12 | # misc 13 | .DS_Store 14 | 15 | # umi 16 | /src/.umi 17 | /src/.umi-production 18 | /src/.umi-test 19 | /.env.local 20 | -------------------------------------------------------------------------------- /client/.prettierignore: -------------------------------------------------------------------------------- 1 | **/*.md 2 | **/*.svg 3 | **/*.ejs 4 | **/*.html 5 | package.json 6 | .umi 7 | .umi-production 8 | .umi-test 9 | -------------------------------------------------------------------------------- /client/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all", 4 | "printWidth": 80, 5 | "overrides": [ 6 | { 7 | "files": ".prettierrc", 8 | "options": { "parser": "json" } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /client/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | singleQuote: true, 3 | trailingComma: 'all', 4 | printWidth: 100, 5 | proseWrap: 'never', 6 | endOfLine: 'lf', 7 | overrides: [ 8 | { 9 | files: '.prettierrc', 10 | options: { 11 | parser: 'json', 12 | }, 13 | }, 14 | { 15 | files: 'document.ejs', 16 | options: { 17 | parser: 'html', 18 | }, 19 | }, 20 | ], 21 | }; 22 | -------------------------------------------------------------------------------- /client/README.md: -------------------------------------------------------------------------------- 1 | # umi project 2 | 3 | ## Getting Started 4 | 5 | Install dependencies, 6 | 7 | ```bash 8 | $ yarn 9 | ``` 10 | 11 | Start the dev server, 12 | 13 | ```bash 14 | $ yarn start 15 | ``` 16 | -------------------------------------------------------------------------------- /client/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@babel/preset-env', 4 | '@babel/preset-typescript', 5 | '@babel/preset-react', 6 | ], 7 | }; 8 | -------------------------------------------------------------------------------- /client/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "jsx": "react-jsx", 4 | "emitDecoratorMetadata": true, 5 | "experimentalDecorators": true, 6 | "baseUrl": "..", 7 | "paths": { 8 | "@/*": ["./src/*"] 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /client/production-server.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const port = 8000; 3 | const app = express(); 4 | 5 | app.use((req, res, next) => { 6 | console.info(`${req.method} ${req.url}`); 7 | next(); 8 | }); 9 | 10 | app.use(express.static('dist')); 11 | app.get(/.*/, function (req, res) { 12 | return res.sendFile(__dirname + '/dist/index.html'); 13 | }); 14 | 15 | // Start server 16 | app.listen(port, () => { 17 | console.log(`Server is now running at http://127.0.0.1:${port}/`); 18 | }); 19 | -------------------------------------------------------------------------------- /client/public/avatars/squirrel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/public/avatars/squirrel.png -------------------------------------------------------------------------------- /client/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/public/favicon.ico -------------------------------------------------------------------------------- /client/public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/public/favicon.png -------------------------------------------------------------------------------- /client/public/images/home-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/public/images/home-dashboard.png -------------------------------------------------------------------------------- /client/public/images/home-devices.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/public/images/home-devices.png -------------------------------------------------------------------------------- /client/public/images/home-services.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/public/images/home-services.png -------------------------------------------------------------------------------- /client/public/images/home-store.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/public/images/home-store.png -------------------------------------------------------------------------------- /client/public/lotties/running_squirrel.lottie: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/public/lotties/running_squirrel.lottie -------------------------------------------------------------------------------- /client/public/lotties/squirrel_find_nut.lottie: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/public/lotties/squirrel_find_nut.lottie -------------------------------------------------------------------------------- /client/public/onboarding/acorn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/public/onboarding/acorn.png -------------------------------------------------------------------------------- /client/public/onboarding/thump.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/public/onboarding/thump.png -------------------------------------------------------------------------------- /client/public/onboarding/tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/public/onboarding/tree.png -------------------------------------------------------------------------------- /client/public/onboarding/tree2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/public/onboarding/tree2.png -------------------------------------------------------------------------------- /client/public/site.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "", 3 | "short_name": "", 4 | "icons": [ 5 | { 6 | "src": "/logo.svg", 7 | "sizes": "192x192", 8 | "type": "image/svg" 9 | } 10 | ], 11 | "theme_color": "#ffffff", 12 | "background_color": "#ffffff", 13 | "display": "standalone" 14 | } 15 | -------------------------------------------------------------------------------- /client/src/access.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @see https://umijs.org/zh-CN/plugins/plugin-access 3 | * */ 4 | import { API } from 'ssm-shared-lib'; 5 | 6 | export default function access( 7 | initialState: { currentUser?: API.CurrentUser } | undefined, 8 | ) { 9 | const { currentUser } = initialState ?? {}; 10 | return { 11 | canAdmin: currentUser && currentUser.access === 'admin', 12 | }; 13 | } 14 | -------------------------------------------------------------------------------- /client/src/components/ComposeEditor/utils/id.ts: -------------------------------------------------------------------------------- 1 | import { MenuElementType } from '@/components/ComposeEditor/types'; 2 | 3 | export function generateId(e: MenuElementType, index: number) { 4 | return `${e.id}-${index}`; 5 | } 6 | -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_alma_darkblue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_alma_darkblue.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_alma_green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_alma_green.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_alma_lightblue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_alma_lightblue.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_alma_purple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_alma_purple.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_alma_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_alma_red.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_alma_yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_alma_yellow.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_alpine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_alpine.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_antix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_antix.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_antix_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_antix_black.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_apple-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_apple-dark.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_arch.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_arco.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_arco.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_artix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_artix.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_bluestar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_bluestar.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_bodhi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_bodhi.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_bodhi_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_bodhi_black.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_bunsenlabs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_bunsenlabs.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_bunsenlabs_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_bunsenlabs_black.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_bunsenlabs_yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_bunsenlabs_yellow.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_bunsenlabs_yellow_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_bunsenlabs_yellow_black.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_centos_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_centos_blue.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_centos_green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_centos_green.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_centos_orange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_centos_orange.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_centos_purple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_centos_purple.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_clear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_clear.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_clear_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_clear_black.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_debian.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_debian.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_deepin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_deepin.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_elementary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_elementary.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_endeavour.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_endeavour.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_endeavour_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_endeavour_black.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_endeavour_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_endeavour_blue.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_endeavour_blue_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_endeavour_blue_black.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_endeavour_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_endeavour_red.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_endeavour_red_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_endeavour_red_black.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_endless.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_endless.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_endless_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_endless_black.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_fedora_newlogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_fedora_newlogo.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_fedora_newlogo_oldcolor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_fedora_newlogo_oldcolor.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_fedora_oldlogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_fedora_oldlogo.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_fedora_oldlogo_newcolor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_fedora_oldlogo_newcolor.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_feren.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_feren.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_feren_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_feren_black.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_garuda_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_garuda_blue.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_garuda_orange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_garuda_orange.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_garuda_orange_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_garuda_orange_light.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_garuda_purple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_garuda_purple.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_generic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_generic.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_gentoo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_gentoo.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_kali.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_kali.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_kali_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_kali_black.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_kaos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_kaos.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_knoppix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_knoppix.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_kubuntu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_kubuntu.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_linux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_linux.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_lite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_lite.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_lite_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_lite_black.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_lubuntu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_lubuntu.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_mabox_v01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_mabox_v01.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_mabox_v02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_mabox_v02.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_mabox_v03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_mabox_v03.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_mageia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_mageia.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_manjaro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_manjaro.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_mint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_mint.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_mx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_mx.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_mx_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_mx_black.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_neon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_neon.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_netrunner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_netrunner.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_nixos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_nixos.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_openmandriva.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_openmandriva.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_parrot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_parrot.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_parrot_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_parrot_black.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_pclinuxos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_pclinuxos.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_peppermint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_peppermint.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_pop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_pop.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_pop_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_pop_black.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_puppy_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_puppy_blue.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_puppy_brown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_puppy_brown.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_q4os_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_q4os_blue.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_q4os_lightblue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_q4os_lightblue.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_q4os_orange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_q4os_orange.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_qubes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_qubes.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_raspios.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_raspios.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_raspios_alt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_raspios_alt.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_rebornos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_rebornos.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_redhat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_redhat.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_redhat_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_redhat_black.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_rosa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_rosa.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_septor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_septor.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_slackware.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_slackware.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_solus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_solus.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_suse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_suse.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_tails.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_tails.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_tinycore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_tinycore.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_ubuntu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_ubuntu.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_ubuntu_cinnamon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_ubuntu_cinnamon.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_ubuntu_dde.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_ubuntu_dde.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_ubuntu_mate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_ubuntu_mate.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_ubuntu_unity_newcolor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_ubuntu_unity_newcolor.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_ubuntu_unity_oldcolor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_ubuntu_unity_oldcolor.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_void.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_void.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_windows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_windows.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_xubuntu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_xubuntu.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/128_zorin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/128_zorin.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/freebsd.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/freebsd.jpeg -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/openbsd_logo_icon_248311.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/openbsd_logo_icon_248311.png -------------------------------------------------------------------------------- /client/src/components/DeviceComponents/OsLogo/img/reactos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/components/DeviceComponents/OsLogo/img/reactos.png -------------------------------------------------------------------------------- /client/src/components/NoDevice/CarouselWithBlur.less: -------------------------------------------------------------------------------- 1 | .imageContainer { 2 | position: relative; 3 | overflow: hidden; 4 | border-radius: 10px; 5 | margin-top: auto; 6 | margin-bottom: auto; 7 | 8 | .blurredImage { 9 | display: block; 10 | width: 100%; 11 | height: auto; 12 | margin-top: auto; 13 | margin-bottom: auto; 14 | box-shadow: 0 0 20px 10px rgba(19, 19, 19, 0.5); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /client/src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Squirrel Servers Manager", 3 | "short_name": "SSM", 4 | "display": "standalone", 5 | "start_url": "./?utm_source=homescreen", 6 | "theme_color": "#002140", 7 | "background_color": "#001529", 8 | "icons": [ 9 | { 10 | "src": "icons/icon-512x512.png", 11 | "sizes": "512x512" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /client/src/pages/404.tsx: -------------------------------------------------------------------------------- 1 | import { history } from '@umijs/max'; 2 | import { Button, Result } from 'antd'; 3 | import React from 'react'; 4 | 5 | const NoFoundPage: React.FC = () => ( 6 | history.push('/')}> 12 | Back Home 13 | 14 | } 15 | /> 16 | ); 17 | 18 | export default NoFoundPage; 19 | -------------------------------------------------------------------------------- /client/src/pages/Dashboard/ChartComponents/Field.less: -------------------------------------------------------------------------------- 1 | 2 | .field { 3 | margin: 0; 4 | overflow: hidden; 5 | white-space: nowrap; 6 | text-overflow: ellipsis; 7 | .label, 8 | .number { 9 | line-height: 22px; 10 | } 11 | .number { 12 | margin-left: 5px; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /client/src/pages/Dashboard/ChartComponents/MiniProgress.tsx: -------------------------------------------------------------------------------- 1 | import { Progress } from 'antd'; 2 | import React from 'react'; 3 | 4 | interface MiniProgressProps { 5 | percent: number; 6 | } 7 | 8 | const MiniProgress: React.FC = ({ percent }) => { 9 | return ( 10 | 15 | ); 16 | }; 17 | 18 | export default React.memo(MiniProgress); 19 | -------------------------------------------------------------------------------- /client/src/pages/Plugins/[pluginId].tsx: -------------------------------------------------------------------------------- 1 | import PluginPageRenderer from '@/plugins/components/PluginPageRenderer'; // Adjust import path if needed 2 | 3 | // This file maps the dynamic route /plugins/:pluginId to the renderer component 4 | export default PluginPageRenderer; 5 | -------------------------------------------------------------------------------- /client/src/pages/User/Login/assets/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/client/src/pages/User/Login/assets/background.png -------------------------------------------------------------------------------- /client/src/services/rest/containers/container-images.ts: -------------------------------------------------------------------------------- 1 | import { request } from '@umijs/max'; 2 | import { API } from 'ssm-shared-lib'; 3 | 4 | const BASE_URL = '/api/container-images'; 5 | 6 | export async function getImages( 7 | params?: any, 8 | options?: Record, 9 | ): Promise> { 10 | return request>(`${BASE_URL}`, { 11 | method: 'GET', 12 | params: { 13 | ...params, 14 | }, 15 | ...(options || {}), 16 | }); 17 | } -------------------------------------------------------------------------------- /client/src/services/rest/diagnostic/diagnostic.ts: -------------------------------------------------------------------------------- 1 | import { request } from '@umijs/max'; 2 | import { API, SsmAgent } from 'ssm-shared-lib'; 3 | 4 | const BASE_URL = '/api/diagnostic'; 5 | 6 | export async function postDeviceDiagnostic( 7 | uuid: string, 8 | options?: { [key: string]: any }, 9 | ) { 10 | return request>( 11 | `${BASE_URL}/${uuid}`, 12 | { 13 | method: 'POST', 14 | ...(options || {}), 15 | }, 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /client/src/services/rest/index.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import * as cron from './scheduler/scheduler'; 3 | import * as deviceauth from './devices/device-credentials'; 4 | import * as device from './devices/devices'; 5 | import * as logs from './logs/logs'; 6 | import * as ansible from './playbooks/playbooks'; 7 | /* eslint-disable */ 8 | import * as user from './users/users'; 9 | import * as usersettings from './usersettings'; 10 | 11 | export default { 12 | user, 13 | device, 14 | cron, 15 | ansible, 16 | logs, 17 | deviceauth, 18 | usersettings, 19 | }; 20 | -------------------------------------------------------------------------------- /client/src/services/rest/logs/logs.ts: -------------------------------------------------------------------------------- 1 | import { request } from '@umijs/max'; 2 | import { API } from 'ssm-shared-lib'; 3 | 4 | const BASE_URL = '/api/logs'; 5 | 6 | export async function getServerLogs( 7 | params?: API.PageParams, 8 | options?: { [key: string]: any }, 9 | ) { 10 | return request>(`${BASE_URL}/server`, { 11 | method: 'GET', 12 | params: { 13 | ...params, 14 | }, 15 | ...(options || {}), 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /client/src/services/rest/scheduler/scheduler.ts: -------------------------------------------------------------------------------- 1 | import { request } from '@umijs/max'; 2 | import { API } from 'ssm-shared-lib'; 3 | 4 | const BASE_URL = '/api/scheduler'; 5 | 6 | export async function getCrons(options?: Record) { 7 | return request(`${BASE_URL}`, { 8 | method: 'GET', 9 | ...(options || {}), 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /client/src/services/rest/smart-failure/smart-failure.ts: -------------------------------------------------------------------------------- 1 | import { request } from '@umijs/max'; 2 | import { API } from 'ssm-shared-lib'; 3 | 4 | const API_PATH = '/api/smart-failure'; 5 | 6 | export async function getAnsibleSmartFailure( 7 | params?: any, 8 | options?: Record, 9 | ): Promise> { 10 | return request>(`${API_PATH}`, { 11 | method: 'GET', 12 | params: { 13 | ...params, 14 | }, 15 | ...(options || {}), 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /client/src/styles/global.css: -------------------------------------------------------------------------------- 1 | /* Add shimmer effect for notifications */ 2 | .shimmer-text { 3 | background: linear-gradient( 4 | 90deg, 5 | #f0f0f0 0%, 6 | #d0d0d0 20%, 7 | #f0f0f0 40%, 8 | #d0d0d0 60%, 9 | #f0f0f0 80% 10 | ); 11 | background-size: 200% auto; 12 | color: transparent; 13 | background-clip: text; 14 | -webkit-background-clip: text; 15 | animation: shimmer 1.5s linear infinite; 16 | } 17 | 18 | @keyframes shimmer { 19 | to { 20 | background-position: 200% center; 21 | } 22 | } -------------------------------------------------------------------------------- /client/src/utils/devicestatus.ts: -------------------------------------------------------------------------------- 1 | enum DeviceStatus { 2 | REGISTERING = 0, 3 | ONLINE = 1, 4 | OFFLINE = 2, 5 | UNMANAGED = 3, 6 | } 7 | 8 | export default DeviceStatus; 9 | -------------------------------------------------------------------------------- /client/src/utils/strings.ts: -------------------------------------------------------------------------------- 1 | export function capitalizeFirstLetter(string) { 2 | if (!string) return ''; 3 | 4 | return string.charAt(0).toUpperCase() + string.slice(1); 5 | } 6 | -------------------------------------------------------------------------------- /client/vitest.config.mts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'path'; 2 | import { defineConfig } from 'vitest/config'; 3 | 4 | export default defineConfig({ 5 | resolve: { 6 | alias: { 7 | '@': resolve(__dirname, 'src'), // Adjust the path as needed. 8 | }, 9 | }, 10 | test: { 11 | globals: true, 12 | environment: 'jsdom', 13 | setupFiles: ['./tests/setupTests.ts'], // Ensure the path to your setup file is correct. 14 | }, 15 | }); 16 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'ts-jest', 3 | testEnvironment: 'node', 4 | roots: ['/server/test'], 5 | testMatch: ['**/*.test.ts'], 6 | transform: { 7 | '^.+\\.tsx?$': 'ts-jest', 8 | }, 9 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], 10 | moduleNameMapper: { 11 | '^@modules/(.*)$': '/server/src/modules/$1', 12 | }, 13 | }; -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { 5 | "@modules/*": ["server/src/modules/*"], 6 | "@common/*": ["server/src/common/*"], 7 | "@config/*": ["server/src/config/*"] 8 | } 9 | }, 10 | "include": ["server/src/**/*"] 11 | } -------------------------------------------------------------------------------- /prometheus/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM prom/prometheus:latest 2 | 3 | # Copy your base Prometheus configuration file to the image 4 | COPY prometheus.base.yml /etc/prometheus/prometheus.base.yml 5 | 6 | # Copy your custom entrypoint script 7 | COPY entrypoint.sh /entrypoint.sh 8 | 9 | USER root 10 | # Make the entrypoint executable 11 | RUN chmod +x /entrypoint.sh 12 | 13 | ENTRYPOINT ["/entrypoint.sh"] -------------------------------------------------------------------------------- /prometheus/prometheus.base.yml: -------------------------------------------------------------------------------- 1 | global: 2 | scrape_interval: 15s # How often Prometheus scrapes targets 3 | 4 | scrape_configs: 5 | - job_name: 'server-metrics' # Server pulling statistics 6 | static_configs: 7 | - targets: 8 | - 'server:3000' # Replace with the address of your server 9 | # Authentication settings (basic_auth) will be injected here dynamically -------------------------------------------------------------------------------- /proxy/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx:1.27.5 2 | LABEL org.opencontainers.image.source=https://github.com/SquirrelCorporation/SquirrelServersManager 3 | LABEL org.opencontainers.image.description="SSM Proxy" 4 | LABEL org.opencontainers.image.licenses="GNU AFFERO GENERAL PUBLIC LICENSE" 5 | 6 | COPY default.conf /etc/nginx/conf.d 7 | COPY www/index.html /usr/share/nginx/html/custom.html 8 | -------------------------------------------------------------------------------- /release.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.1.29" 3 | } 4 | -------------------------------------------------------------------------------- /server-demo/nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "watch" : [ 3 | "src", 4 | ".env" 5 | ], 6 | "ext":"js,ts,json", 7 | "verbose": true, 8 | "ignore": [ 9 | "src/logs/*", 10 | "src/**/*.{spec,test}.ts", 11 | "src/**/ansible/artifacts/*", 12 | "src/**/ansible/inventory/*.json", 13 | "src/tests/helpers/directory-tree/test_data/*" 14 | ], 15 | "exec": "ts-node --transpile-only src/index.ts" 16 | 17 | } 18 | 19 | -------------------------------------------------------------------------------- /server-demo/src/data/ansible-smart-failure.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "unreachable", 3 | "message": "fatal: [192.168.0.69]: UNREACHABLE! => {", 4 | "cause": "The device may be down or unreachable.", 5 | "resolution": "Check the device network connectivity and ensure you entered the right IP." 6 | } 7 | -------------------------------------------------------------------------------- /server-demo/src/data/device-auth.json: -------------------------------------------------------------------------------- 1 | { 2 | "authType": "userPwd", 3 | "sshUser": "root", 4 | "sshPwd": "REDACTED", 5 | "sshPort": 22, 6 | "becomeMethod": "sudo", 7 | "becomePass": "REDACTED", 8 | "customDockerSSH": false, 9 | "customDockerForcev6": false, 10 | "customDockerForcev4": false, 11 | "customDockerAgentForward": false, 12 | "customDockerTryKeyboard": false 13 | } 14 | -------------------------------------------------------------------------------- /server-demo/src/data/dry-run.json: -------------------------------------------------------------------------------- 1 | { 2 | "validating": false, 3 | "message": "env file /tmp/f81f4b0a-e234-42e5-b6cc-46e981f6af74/.env not found: stat /tmp/f81f4b0a-e234-42e5-b6cc-46e981f6af74/.env: no such file or directory\n" 4 | } -------------------------------------------------------------------------------- /server-demo/src/data/performance.json: -------------------------------------------------------------------------------- 1 | { 2 | "currentMem": 81.13243822285165, 3 | "previousMem": 81.80204405782048, 4 | "currentCpu": 6.394355901737567, 5 | "previousCpu": 7.367709685795897, 6 | "message": "HEALTHY", 7 | "danger": false 8 | } 9 | -------------------------------------------------------------------------------- /server-demo/src/index.ts: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import routes from "./routes"; 3 | import { errorHandler } from "./utils/ErrorHandler"; 4 | 5 | const app = express(); 6 | app.use(express.json()); 7 | app.use("/", routes); 8 | app.use(errorHandler); 9 | app.listen(3000, () => 10 | console.log(` 11 | 🐿 Squirrel Servers Manager 12 | 🚀 Server ready at: http://localhost:3000`), 13 | ); 14 | -------------------------------------------------------------------------------- /server-demo/src/routes/ansible.ts: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import ansibleConf from "../data/ansible-conf.json"; 3 | import smartFailure from "../data/ansible-smart-failure.json"; 4 | import { SuccessResponse } from "../utils/ApiResponse"; 5 | import asyncHandler from "../utils/AsyncHandler"; 6 | 7 | const router = express.Router(); 8 | 9 | 10 | 11 | export default router; 12 | -------------------------------------------------------------------------------- /server-demo/src/utils/AsyncHandler.ts: -------------------------------------------------------------------------------- 1 | import { NextFunction, Request, Response } from "express"; 2 | 3 | type AsyncFunction = ( 4 | req: Request, 5 | res: Response, 6 | next: NextFunction, 7 | ) => Promise; 8 | 9 | export default (execution: AsyncFunction) => 10 | (req: Request, res: Response, next: NextFunction) => { 11 | execution(req, res, next).catch(next); 12 | }; 13 | -------------------------------------------------------------------------------- /server-demo/src/utils/ErrorHandler.ts: -------------------------------------------------------------------------------- 1 | import { NextFunction, Request, Response } from "express"; 2 | import { ApiError, InternalError } from "./ApiError"; 3 | 4 | export const errorHandler = ( 5 | err: Error, 6 | req: Request, 7 | res: Response, 8 | next: NextFunction, 9 | ) => { 10 | if (err instanceof ApiError) { 11 | ApiError.handle(err, res, req); 12 | } else { 13 | ApiError.handle(new InternalError(), res, req); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /server/.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | node_modules 3 | -------------------------------------------------------------------------------- /server/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /server/.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | /node_modules 3 | /npm-debug.log* 4 | /yarn-error.log 5 | /yarn.lock 6 | /src/ansible/artifacts 7 | /src/ansible/inventory/hosts.json 8 | /coverage 9 | # production 10 | /dist 11 | 12 | # misc 13 | .DS_Store 14 | ./node_modules/* 15 | /node_modules/* 16 | /documentation/SECURITY_SCANNER_PLUGIN_PLAN.md 17 | -------------------------------------------------------------------------------- /server/.prettierignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /server/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "arrowParens": "always", 4 | "printWidth": 100, 5 | "proseWrap": "never", 6 | "endOfLine": "lf" 7 | } 8 | -------------------------------------------------------------------------------- /server/__mocks__/fs.cjs: -------------------------------------------------------------------------------- 1 | const { fs } = require('memfs'); 2 | 3 | module.exports = fs; 4 | -------------------------------------------------------------------------------- /server/__mocks__/fs/promises.cjs: -------------------------------------------------------------------------------- 1 | const { fs } = require('memfs'); 2 | 3 | module.exports = fs.promises; 4 | -------------------------------------------------------------------------------- /server/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "./", 4 | "paths": { 5 | "@modules/*": ["src/modules/*"], 6 | "@common/*": ["src/common/*"], 7 | "@config/*": ["src/config/*"] 8 | } 9 | }, 10 | "include": ["src/**/*"] 11 | } -------------------------------------------------------------------------------- /server/nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "watch" : [ 3 | "src", 4 | ".env" 5 | ], 6 | "ext":"js,ts,json", 7 | "verbose": true, 8 | "ignore": [ 9 | "src/logs/*", 10 | "src/**/*.{spec,test}.ts", 11 | "src/**/ansible/artifacts/*", 12 | "src/**/ansible/inventory/*.json", 13 | "src/tests/helpers/directory-tree/test_data/*", 14 | "src/**/test-setup.ts" 15 | ], 16 | "exec": "ts-node --transpile-only -r tsconfig-paths/register src/main.ts" 17 | } 18 | -------------------------------------------------------------------------------- /server/src/__tests__/integration/server.ts: -------------------------------------------------------------------------------- 1 | import app from '../../App'; 2 | 3 | app.setupRoutes(); 4 | 5 | const expressAppForTest = app.getExpressApp(); 6 | export default expressAppForTest; 7 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000000/agent/_checkDeviceBeforeAdd.json: -------------------------------------------------------------------------------- 1 | { 2 | "playableInBatch": false, 3 | "uniqueQuickRef": "checkDeviceBeforeAdd" 4 | } 5 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000000/agent/_restartAgent.json: -------------------------------------------------------------------------------- 1 | { 2 | "playableInBatch": true, 3 | "uniqueQuickRef": "restartAgent", 4 | "extraVars": [ 5 | { 6 | "extraVar": "_ssm_installMethod", 7 | "required": true, 8 | "type": "CONTEXT", 9 | "deletable": false 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000000/agent/_retrieveAgentLogs.json: -------------------------------------------------------------------------------- 1 | { 2 | "playableInBatch": false, 3 | "uniqueQuickRef": "retrieveAgentLogs", 4 | "extraVars": [ 5 | { 6 | "extraVar": "_ssm_agentLogPath", 7 | "required": false, 8 | "type": "CONTEXT", 9 | "deletable": false 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000000/agent/_uninstallAgent.json: -------------------------------------------------------------------------------- 1 | { 2 | "playableInBatch": false, 3 | "uniqueQuickRef": "uninstallAgent", 4 | "extraVars": [ 5 | { 6 | "extraVar": "_ssm_agentLogPath", 7 | "required": false, 8 | "type": "CONTEXT", 9 | "deletable": false 10 | }, 11 | { 12 | "extraVar": "_ssm_installMethod", 13 | "required": true, 14 | "type": "CONTEXT", 15 | "deletable": false 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000000/agent/group_vars/all.yml: -------------------------------------------------------------------------------- 1 | # COMMON 2 | agent_log_path: "{{ _ssm_agentLogPath | default(omit) }}" 3 | valid_install_methods: 4 | - node 5 | - node_enhanced_playbook 6 | - docker 7 | 8 | # NODE AGENT 9 | node_agent_base_path: /opt/squirrelserversmanager 10 | node_agent_nvm_dir: "/root/.nvm" 11 | 12 | # DOCKER AGENT 13 | docker_agent_docker_compose_dir: /opt/ssm-agent 14 | docker_agent_docker_volume: ssm-agent-data 15 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000000/agent/roles/install_agent_docker_conf/tasks/copy_files.yml: -------------------------------------------------------------------------------- 1 | - name: Copy Docker Compose file 2 | copy: 3 | src: files/docker-compose.yml 4 | dest: "{{ docker_agent_docker_compose_dir }}/docker-compose.yml" 5 | 6 | - name: Create .env file for Docker Compose 7 | copy: 8 | content: | 9 | API_URL_MASTER={{ _ssm_masterNodeUrl }} 10 | HOST_ID={{ _ssm_deviceId }} 11 | dest: "{{ docker_agent_docker_compose_dir }}/.env" 12 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000000/agent/roles/install_agent_docker_conf/tasks/create_directories.yml: -------------------------------------------------------------------------------- 1 | - name: Create Docker Compose directory 2 | file: 3 | path: "{{ docker_agent_docker_compose_dir }}" 4 | state: directory 5 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000000/agent/roles/install_agent_docker_conf/tasks/main.yml: -------------------------------------------------------------------------------- 1 | 2 | - name: "Create directories on host" 3 | include_tasks: create_directories.yml 4 | 5 | - name: "Copy files on host" 6 | include_tasks: copy_files.yml 7 | 8 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000000/agent/roles/install_agent_node/tasks/check_node_npm.yml: -------------------------------------------------------------------------------- 1 | - name: Check if NodeJS, npm, and NVM.sh are installed 2 | block: 3 | - name: Check if NodeJS is installed 4 | command: which node 5 | register: node_check 6 | ignore_errors: true 7 | changed_when: false 8 | 9 | - name: Check if npm is installed 10 | command: which npm 11 | register: npm_check 12 | ignore_errors: true 13 | changed_when: false 14 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000000/agent/roles/install_agent_node/tasks/install_git.yml: -------------------------------------------------------------------------------- 1 | - name: Check if Git is installed 2 | command: which git 3 | register: git_check 4 | ignore_errors: true 5 | changed_when: false 6 | 7 | - name: Install Git 8 | package: 9 | name: git 10 | state: present 11 | when: git_check.rc != 0 12 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000000/agent/roles/install_agent_node_v2/tasks/npm_install.yml: -------------------------------------------------------------------------------- 1 | - name: NPM install 2 | shell: "{{ mg_user_shell.command + ' \" npm install\"' }}" 3 | args: 4 | chdir: "{{ base_path }}" 5 | register: npm_install 6 | failed_when: npm_install.rc != 0 7 | 8 | - name: NPM run build 9 | shell: "{{ mg_user_shell.command + ' \" npm run build\"' }}" 10 | args: 11 | chdir: "{{ base_path }}" 12 | register: npm_build 13 | failed_when: npm_build.rc != 0 14 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000000/agent/roles/install_agent_node_v2/tasks/pm2_install.yml: -------------------------------------------------------------------------------- 1 | - name: Check if PM2 is installed 2 | shell: "{{ mg_user_shell.command + ' \"npm list -g pm2\"' }}" 3 | register: pm2_check 4 | ignore_errors: true 5 | changed_when: false 6 | 7 | - name: Install "PM2" node.js package globally 8 | shell: "{{ mg_user_shell.command + ' \"npm install -g pm2\"' }}" 9 | when: pm2_check.rc != 0 10 | 11 | - name: Install PM2 LogRotate 12 | shell: "{{ mg_user_shell.command + ' \" pm2 install pm2-logrotate\"' }}" 13 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000000/agent/roles/install_agent_node_v2/tasks/report_status.yml: -------------------------------------------------------------------------------- 1 | - name: Report execution status 2 | debug: 3 | msg: "Agent installation completed successfully" 4 | when: git_checkout.changed and npm_install.rc == 0 and npm_build.rc == 0 and pm2_start.rc == 0 5 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000000/agent/roles/install_docker/tasks/check_docker.yml: -------------------------------------------------------------------------------- 1 | - name: Check if Docker is installed 2 | ansible.builtin.command: which docker 3 | register: docker_check 4 | ignore_errors: true 5 | changed_when: false 6 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000000/agent/roles/install_docker/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: "Check Docker is installed" 2 | include_tasks: check_docker.yml 3 | 4 | - name: "Install Docker if needed" 5 | include_tasks: install_docker.yml 6 | when: 7 | - docker_check.rc != 0 8 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000000/agent/roles/remove_agent_docker_volume/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: Check if Docker volume exists 2 | command: docker volume inspect ssm-agent-data 3 | register: volume_check 4 | ignore_errors: yes 5 | 6 | - name: Remove existing Docker volume if it exists 7 | command: docker volume rm {{ docker_agent_docker_volume }} 8 | when: volume_check.rc == 0 9 | ignore_errors: yes 10 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000000/agent/roles/restart_agent_docker/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: Stop Docker agent service 2 | include_role: 3 | name: stop_agent_docker 4 | 5 | - name: Ensure Docker Compose services are running 6 | community.docker.docker_compose_v2: 7 | project_src: "{{ docker_agent_docker_compose_dir }}" 8 | state: present 9 | detached: true 10 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000000/agent/roles/start_agent_docker/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: Ensure Docker Compose services are running 2 | community.docker.docker_compose_v2: 3 | project_src: "{{ docker_agent_docker_compose_dir }}" 4 | state: present 5 | recreate: always 6 | pull: always 7 | remove_orphans: yes 8 | 9 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000000/agent/roles/stop_agent_docker/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: Ensure Docker Compose services are stoped 2 | community.docker.docker_compose_v2: 3 | project_src: "{{ docker_agent_docker_compose_dir }}" 4 | state: absent 5 | 6 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000000/agent/roles/uninstall_agent_docker/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: Stop Agent 2 | include_role: 3 | name: stop_agent_docker 4 | 5 | - name: Remove volume 6 | include_role: 7 | name: remove_agent_docker_volume 8 | 9 | - name: Recursively remove Squirrel Servers Manager directory 10 | ansible.builtin.file: 11 | path: "{{ docker_agent_docker_compose_dir }}" 12 | state: absent 13 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000000/device/_ping.json: -------------------------------------------------------------------------------- 1 | { 2 | "uniqueQuickRef": "ping" 3 | } 4 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000000/device/_ping.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # ,;;:;, 3 | # ;;;;; 4 | # ,:;;:; ,'=. 5 | # ;:;:;' .=" ,'_\ 6 | # ':;:;,/ ,__:=@ 7 | # ';;:; =./)_ 8 | # `"=\_ )_"` 9 | # ``'"` 10 | # Playbook Name: Ansible Ping 11 | # Description: This playbook executes an Ansible ping on the host. 12 | # Module: SSM-CORE 13 | # Tags: ping, connectivity, ansible, ssh 14 | 15 | - hosts: all 16 | tasks: 17 | - name: Test Connection 18 | ping: 19 | timeout: 600 20 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000000/device/_reboot.json: -------------------------------------------------------------------------------- 1 | { 2 | "playableInBatch": true, 3 | "uniqueQuickRef": "reboot" 4 | } 5 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000000/device/_reboot.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # ,;;:;, 3 | # ;;;;; 4 | # ,:;;:; ,'=. 5 | # ;:;:;' .=" ,'_\ 6 | # ':;:;,/ ,__:=@ 7 | # ';;:; =./)_ 8 | # `"=\_ )_"` 9 | # ``'"` 10 | # Playbook Name: Reboot 11 | # Description: This playbook reboots unconditionally a machine 12 | # Module: SSM-CORE 13 | # Tags: reboot, restart, host 14 | 15 | - hosts: all 16 | become: true 17 | tasks: 18 | - name: Unconditionally reboot the machine 19 | ansible.builtin.reboot: 20 | 21 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000000/device/_upgrade.json: -------------------------------------------------------------------------------- 1 | { 2 | "playableInBatch": true, 3 | "uniqueQuickRef": "upgrade" 4 | } 5 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000000/device/roles/upgrade_host_package/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # tasks/main.yml 3 | 4 | - include_tasks: debian.yml 5 | when: ansible_distribution in ["Debian", "Ubuntu"] 6 | 7 | - include_tasks: rhel.yml 8 | when: ansible_distribution in ["CentOS", "RedHat"] 9 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000000/docker/_createDockerVolume.json: -------------------------------------------------------------------------------- 1 | { 2 | "playableInBatch": true, 3 | "uniqueQuickRef": "createDockerVolume", 4 | "extraVars": [ 5 | { 6 | "extraVar": "name", 7 | "required": true, 8 | "type": "MANUAL", 9 | "deletable": false 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000000/docker/_dockerCompose.json: -------------------------------------------------------------------------------- 1 | { 2 | "playableInBatch": true, 3 | "uniqueQuickRef": "deploy", 4 | "extraVars": [ 5 | { 6 | "extraVar": "project", 7 | "required": true, 8 | "type": "MANUAL", 9 | "deletable": false 10 | }, 11 | { 12 | "extraVar": "definition", 13 | "required": true, 14 | "type": "MANUAL", 15 | "deletable": false 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000001/utils/fact-scan.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Scan host for facts 3 | hosts: all 4 | become: true 5 | gather_facts: true 6 | 7 | tasks: 8 | - name: Collect package facts 9 | ansible.builtin.package_facts: 10 | 11 | - name: Collect service facts 12 | ansible.builtin.service_facts: 13 | 14 | - name: Debug gathered facts 15 | ansible.builtin.debug: 16 | var: ansible_facts 17 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000001/utils/ping-ssm-api-url.json: -------------------------------------------------------------------------------- 1 | { 2 | "playableInBatch": true, 3 | "extraVars": [ 4 | { 5 | "extraVar": "_ssm_masterNodeUrl", 6 | "required": true, 7 | "type": "SHARED" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /server/src/ansible/00000000-0000-0000-0000-000000000001/utils/ping-ssm-api-url.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Ping SSM API URL 3 | hosts: all 4 | tasks: 5 | - name: Check that you can connect (GET) to the API and it returns a status 200 6 | ansible.builtin.uri: 7 | url: "{{ _ssm_masterNodeUrl }}/api/ping" 8 | -------------------------------------------------------------------------------- /server/src/ansible/env/cmdline: -------------------------------------------------------------------------------- 1 | --vault-password-file ssm-ansible-vault-password-client.py 2 | 3 | -------------------------------------------------------------------------------- /server/src/ansible/requirements.txt: -------------------------------------------------------------------------------- 1 | requests 2 | mock 3 | requests_unixsocket 4 | ansible-runner 5 | -------------------------------------------------------------------------------- /server/src/core/bootstrap/bootstrap.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { BootstrapService } from './bootstrap.service'; 3 | 4 | /** 5 | * Module responsible for application bootstrap logic. 6 | */ 7 | @Module({ 8 | providers: [BootstrapService], 9 | exports: [BootstrapService], // Export if needed by other modules, otherwise optional 10 | }) 11 | export class BootstrapModule {} 12 | -------------------------------------------------------------------------------- /server/src/core/events/restart-server.event.ts: -------------------------------------------------------------------------------- 1 | export class RestartServerEvent { 2 | constructor() {} 3 | // Can add properties if needed later (e.g., reason for restart) 4 | } 5 | -------------------------------------------------------------------------------- /server/src/decorators/public.decorator.ts: -------------------------------------------------------------------------------- 1 | import { SetMetadata } from '@nestjs/common'; 2 | 3 | export const IS_PUBLIC_KEY = 'isPublic'; 4 | export const Public = () => SetMetadata(IS_PUBLIC_KEY, true); 5 | -------------------------------------------------------------------------------- /server/src/decorators/roles.decorator.ts: -------------------------------------------------------------------------------- 1 | import { SetMetadata } from '@nestjs/common'; 2 | 3 | export const ROLES_KEY = 'roles'; 4 | export const Roles = (...roles: string[]) => SetMetadata(ROLES_KEY, roles); 5 | -------------------------------------------------------------------------------- /server/src/decorators/skip-throttle.decorator.ts: -------------------------------------------------------------------------------- 1 | import { SetMetadata } from '@nestjs/common'; 2 | 3 | // Decorator to skip rate limiting for specific routes 4 | export const SkipThrottle = () => SetMetadata('skipThrottle', true); -------------------------------------------------------------------------------- /server/src/decorators/user.decorator.ts: -------------------------------------------------------------------------------- 1 | import { ExecutionContext, createParamDecorator } from '@nestjs/common'; 2 | 3 | export const User = createParamDecorator((data: unknown, ctx: ExecutionContext) => { 4 | const request = ctx.switchToHttp().getRequest(); 5 | return request.user; 6 | }); 7 | -------------------------------------------------------------------------------- /server/src/infrastructure/adapters/git/errors/index.ts: -------------------------------------------------------------------------------- 1 | export * from './errors.util'; -------------------------------------------------------------------------------- /server/src/infrastructure/adapters/git/index.ts: -------------------------------------------------------------------------------- 1 | export * from './errors'; 2 | export * from './interfaces'; 3 | export * from './utils'; 4 | export * from './services'; -------------------------------------------------------------------------------- /server/src/infrastructure/adapters/git/interfaces/index.ts: -------------------------------------------------------------------------------- 1 | export * from './git.interface'; -------------------------------------------------------------------------------- /server/src/infrastructure/adapters/git/services/index.ts: -------------------------------------------------------------------------------- 1 | export * from './inspect.service'; 2 | export * from './clone.service'; 3 | export * from './sync.service'; 4 | export * from './commit-and-sync.service'; 5 | export * from './force-pull.service'; 6 | export * from './init-git.service'; -------------------------------------------------------------------------------- /server/src/infrastructure/adapters/git/utils/default-info.util.ts: -------------------------------------------------------------------------------- 1 | import { SsmGit } from 'ssm-shared-lib'; 2 | 3 | export const defaultGitInfo = { 4 | email: 'gitsync@gmail.com', 5 | gitUserName: 'gitsync', 6 | branch: 'main', 7 | remote: 'origin', 8 | gitService: SsmGit.Services.Github, 9 | env: { 10 | GIT_SSL_NO_VERIFY: 'false', 11 | }, 12 | }; 13 | -------------------------------------------------------------------------------- /server/src/infrastructure/adapters/git/utils/git.util.ts: -------------------------------------------------------------------------------- 1 | export const getGitUrlWithGitSuffix = (url: string): string => `${url}.git`; 2 | export const getGitUrlWithOutGitSuffix = (url: string): string => url.replace(/\.git$/, ''); 3 | -------------------------------------------------------------------------------- /server/src/infrastructure/adapters/git/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './git.util'; 2 | export * from './default-info.util'; 3 | export * from './credential.util'; 4 | export * from './init.util'; -------------------------------------------------------------------------------- /server/src/infrastructure/adapters/proxmox/CREDIT.md: -------------------------------------------------------------------------------- 1 | https://github.com/UrielCh/proxmox-api 2 | -------------------------------------------------------------------------------- /server/src/infrastructure/adapters/proxmox/index.ts: -------------------------------------------------------------------------------- 1 | export * from './services'; -------------------------------------------------------------------------------- /server/src/infrastructure/adapters/proxmox/services/index.ts: -------------------------------------------------------------------------------- 1 | export * from './proxmox-engine.service'; 2 | export * from './qm-monitor.service'; 3 | export * from './constructor.service'; 4 | export * from './proxy.service'; 5 | -------------------------------------------------------------------------------- /server/src/infrastructure/adapters/ssh/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ssh-credentials.adapter'; 2 | export * from './axios-ssh.adapter'; 3 | export * from './custom-agent.adapter'; -------------------------------------------------------------------------------- /server/src/infrastructure/auth/strategies/jwt-auth-guard.interface.ts: -------------------------------------------------------------------------------- 1 | import { ExecutionContext } from '@nestjs/common'; 2 | 3 | export const JWT_AUTH_GUARD = 'JWT_AUTH_GUARD'; 4 | 5 | /** 6 | * Interface for the JWT Auth Guard 7 | */ 8 | export interface IJwtAuthGuard { 9 | /** 10 | * Determine if a request can activate the route 11 | * @param context Execution context 12 | * @returns Boolean indicating if the request can activate the route 13 | */ 14 | canActivate(context: ExecutionContext): boolean | Promise; 15 | } 16 | -------------------------------------------------------------------------------- /server/src/infrastructure/auth/strategies/jwt-strategy.interface.ts: -------------------------------------------------------------------------------- 1 | import { IUser } from '../../../modules/users/domain/entities/user.entity'; 2 | 3 | export const JWT_STRATEGY = 'JWT_STRATEGY'; 4 | 5 | /** 6 | * Interface for the JWT Strategy 7 | */ 8 | export interface IJwtStrategy { 9 | /** 10 | * Validate a JWT payload 11 | * @param payload JWT payload 12 | * @returns User if validation is successful 13 | */ 14 | validate(payload: any): Promise; 15 | } 16 | -------------------------------------------------------------------------------- /server/src/infrastructure/common/ansible/ansible-task.util.ts: -------------------------------------------------------------------------------- 1 | import { SsmAnsible } from 'ssm-shared-lib'; 2 | 3 | export const isFinalStatus = (status: string): boolean => { 4 | return ( 5 | status === SsmAnsible.AnsibleTaskStatus.FAILED || 6 | status === SsmAnsible.AnsibleTaskStatus.SUCCESS || 7 | status === SsmAnsible.AnsibleTaskStatus.CANCELED || 8 | status === SsmAnsible.AnsibleTaskStatus.TIMEOUT 9 | ); 10 | }; 11 | -------------------------------------------------------------------------------- /server/src/infrastructure/common/ansible/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ansible-task.util'; 2 | export * from './ansible-configuration.util'; -------------------------------------------------------------------------------- /server/src/infrastructure/common/directory-tree/__tests__/constants.ts: -------------------------------------------------------------------------------- 1 | export const TEST_DATA_DIRECTORY = `${__dirname}/test_data`; 2 | -------------------------------------------------------------------------------- /server/src/infrastructure/common/directory-tree/__tests__/depth/fixtureZeroDepth.ts: -------------------------------------------------------------------------------- 1 | import { TEST_DATA_DIRECTORY } from '../constants'; 2 | 3 | const tree = { 4 | path: `${TEST_DATA_DIRECTORY}`, 5 | name: 'test_data', 6 | type: 'directory', 7 | }; 8 | 9 | export default tree; 10 | -------------------------------------------------------------------------------- /server/src/infrastructure/common/directory-tree/__tests__/test_data/file_a.txt: -------------------------------------------------------------------------------- 1 | Hello world 2 | -------------------------------------------------------------------------------- /server/src/infrastructure/common/directory-tree/__tests__/test_data/some_dir/another_dir/file_a.txt: -------------------------------------------------------------------------------- 1 | Hello world 2 | -------------------------------------------------------------------------------- /server/src/infrastructure/common/directory-tree/__tests__/test_data/some_dir/file_a.txt: -------------------------------------------------------------------------------- 1 | Hello world 2 | -------------------------------------------------------------------------------- /server/src/infrastructure/common/directory-tree/__tests__/test_data/some_dir_2/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/server/src/infrastructure/common/directory-tree/__tests__/test_data/some_dir_2/.gitkeep -------------------------------------------------------------------------------- /server/src/infrastructure/common/directory-tree/index.ts: -------------------------------------------------------------------------------- 1 | export * from './directory-tree.util'; -------------------------------------------------------------------------------- /server/src/infrastructure/common/dns/index.ts: -------------------------------------------------------------------------------- 1 | export * from './dns.util'; -------------------------------------------------------------------------------- /server/src/infrastructure/common/docker/index.ts: -------------------------------------------------------------------------------- 1 | export * from './docker-compose.util'; 2 | export * from './docker-compose-json-transformer.util'; 3 | export * from './utils'; -------------------------------------------------------------------------------- /server/src/infrastructure/common/docker/utils.ts: -------------------------------------------------------------------------------- 1 | import yaml from 'js-yaml'; 2 | import logger from '../../../logger'; 3 | 4 | export function extractTopLevelName(content: string): string | undefined { 5 | try { 6 | const parsedYaml = yaml.load(content); 7 | if (typeof parsedYaml === 'object' && parsedYaml !== null) { 8 | return (parsedYaml as { [key: string]: any }).name; 9 | } 10 | } catch (err: any) { 11 | logger.error('Error parsing YAML:' + err.message); 12 | } 13 | return undefined; 14 | } 15 | -------------------------------------------------------------------------------- /server/src/infrastructure/common/files/index.ts: -------------------------------------------------------------------------------- 1 | export * from './recursive-find.util'; -------------------------------------------------------------------------------- /server/src/infrastructure/common/index.ts: -------------------------------------------------------------------------------- 1 | export * from './directory-tree'; 2 | export * from './dns'; 3 | export * from './docker'; 4 | export * from './files'; 5 | export * from './query'; 6 | export * from './redis'; 7 | export * from './ansible'; 8 | export * from './utils'; -------------------------------------------------------------------------------- /server/src/infrastructure/common/query/__tests__/mock-pagination.util.ts: -------------------------------------------------------------------------------- 1 | // Mock pagination utility function 2 | export function paginate(data: T[], current = 1, pageSize = 10): T[] { 3 | if (!data) { 4 | return []; 5 | } 6 | return [...data].slice( 7 | ((current as number) - 1) * (pageSize as number), 8 | (current as number) * (pageSize as number), 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /server/src/infrastructure/common/query/index.ts: -------------------------------------------------------------------------------- 1 | export * from './filter.util'; 2 | export * from './pagination.util'; 3 | export * from './sorter.util'; -------------------------------------------------------------------------------- /server/src/infrastructure/common/query/pagination.util.ts: -------------------------------------------------------------------------------- 1 | // Pagination logic 2 | export function paginate(data: T[], current = 1, pageSize = 10): T[] { 3 | if (!data) { 4 | return []; 5 | } 6 | return [...data].slice( 7 | ((current as number) - 1) * (pageSize as number), 8 | (current as number) * (pageSize as number), 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /server/src/infrastructure/common/redis/index.ts: -------------------------------------------------------------------------------- 1 | export * from './redis-info.util'; -------------------------------------------------------------------------------- /server/src/infrastructure/common/redis/redis-info.util.ts: -------------------------------------------------------------------------------- 1 | // Helper to parse Redis INFO output into an object 2 | export function parseRedisInfo(info: string) { 3 | return info 4 | .split('\n') 5 | .filter((line) => line && !line.startsWith('#')) 6 | .reduce( 7 | (acc, line) => { 8 | const [key, value] = line.split(':'); 9 | if (key && value) { 10 | acc[key.trim()] = value.trim(); 11 | } 12 | return acc; 13 | }, 14 | {} as Record, 15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /server/src/infrastructure/common/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './utils'; -------------------------------------------------------------------------------- /server/src/infrastructure/exceptions/index.ts: -------------------------------------------------------------------------------- 1 | // Export all exceptions 2 | export * from './app-exceptions'; 3 | export * from './exception-factory'; -------------------------------------------------------------------------------- /server/src/infrastructure/index.ts: -------------------------------------------------------------------------------- 1 | // Export all infrastructure modules 2 | export * from './adapters/git'; 3 | export * from './adapters/proxmox'; 4 | export * from './adapters/ssh'; 5 | export * from './common'; 6 | export * from './security'; 7 | 8 | // Note: The following modules are already existing NestJS modules 9 | // and should be imported directly rather than through this barrel export 10 | // - filters 11 | // - interceptors 12 | // - plugins 13 | // - prometheus 14 | // - ssh (NestJS module) 15 | -------------------------------------------------------------------------------- /server/src/infrastructure/plugins/plugins.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { PluginModule } from './plugin-system'; 3 | import { PluginsController } from './plugins.controller'; 4 | import { PluginStoreModule } from './store/plugin-store.module'; 5 | 6 | @Module({ 7 | imports: [PluginModule.forRoot(), PluginStoreModule], 8 | controllers: [PluginsController], 9 | providers: [], 10 | }) 11 | export class PluginsModule {} 12 | -------------------------------------------------------------------------------- /server/src/infrastructure/security/index.ts: -------------------------------------------------------------------------------- 1 | export * from './vault-crypto'; 2 | export * from './throttler/throttler.module'; 3 | export * from './roles/roles.guard'; 4 | export * from './roles/resource-action.decorator'; -------------------------------------------------------------------------------- /server/src/infrastructure/security/vault-crypto/index.ts: -------------------------------------------------------------------------------- 1 | export * from './services'; 2 | export * from './utils'; 3 | export * from './types'; 4 | -------------------------------------------------------------------------------- /server/src/infrastructure/security/vault-crypto/services/index.ts: -------------------------------------------------------------------------------- 1 | export * from './vault.service'; 2 | -------------------------------------------------------------------------------- /server/src/infrastructure/security/vault-crypto/types/index.d.ts: -------------------------------------------------------------------------------- 1 | export type DerivedKey = { 2 | key: Buffer; 3 | hmacKey: Buffer; 4 | iv: Buffer; 5 | }; 6 | export type Unpacked = { 7 | salt: Buffer; 8 | hmac: Buffer; 9 | ciphertext: Buffer; 10 | }; 11 | -------------------------------------------------------------------------------- /server/src/infrastructure/security/vault-crypto/types/index.ts: -------------------------------------------------------------------------------- 1 | export type DerivedKey = { 2 | key: Buffer; 3 | hmacKey: Buffer; 4 | iv: Buffer; 5 | }; 6 | 7 | export type Unpacked = { 8 | salt: Buffer; 9 | hmac: Buffer; 10 | ciphertext: Buffer; 11 | }; -------------------------------------------------------------------------------- /server/src/infrastructure/security/vault-crypto/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './binascii.util'; 2 | export * from './pkcs7.util'; -------------------------------------------------------------------------------- /server/src/infrastructure/websocket-auth/ws-auth.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { JwtModule } from '@nestjs/jwt'; 3 | import { SECRET } from '../../config'; 4 | import { WsAuthGuard } from './ws-auth.guard'; 5 | 6 | @Module({ 7 | imports: [ 8 | JwtModule.register({ 9 | secret: SECRET, 10 | signOptions: { expiresIn: '8h' }, 11 | }), 12 | ], 13 | providers: [WsAuthGuard], 14 | exports: [WsAuthGuard, JwtModule], 15 | }) 16 | export class WsAuthModule {} 17 | -------------------------------------------------------------------------------- /server/src/modules/ansible-config/constants.ts: -------------------------------------------------------------------------------- 1 | import { SSM_DATA_PATH } from '../../config'; 2 | 3 | export const ANSIBLE_CONFIG_PATH = `${SSM_DATA_PATH}/config`; 4 | export const ANSIBLE_CONFIG_FILE = `${ANSIBLE_CONFIG_PATH}/ansible.cfg`; 5 | -------------------------------------------------------------------------------- /server/src/modules/ansible-config/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ansible-config.module'; 2 | export * from './presentation/controllers/ansible-config.controller'; 3 | export * from './application/services/ansible-config.service'; 4 | export * from './presentation/dtos/ansible-config.dto'; 5 | export * from './presentation/interfaces/config.interface'; 6 | export * from './constants'; 7 | -------------------------------------------------------------------------------- /server/src/modules/ansible-config/presentation/interfaces/config.interface.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Interface for a single configuration entry 3 | */ 4 | export interface ConfigEntry { 5 | value: string; 6 | deactivated: boolean; 7 | description?: string; 8 | } 9 | 10 | /** 11 | * Interface for the complete Ansible configuration 12 | */ 13 | export interface AnsibleConfig { 14 | [section: string]: { 15 | [key: string]: ConfigEntry; 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /server/src/modules/ansible-vaults/domain/entities/ansible-vault.entity.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * AnsibleVault entity interface in the domain layer 3 | */ 4 | export interface IAnsibleVault { 5 | _id?: string; 6 | vaultId: string; 7 | password: string; 8 | createdAt?: Date; 9 | updatedAt?: Date; 10 | } -------------------------------------------------------------------------------- /server/src/modules/ansible/domain/entities/ansible-task-status.entity.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Domain entity for Ansible task status 3 | */ 4 | export interface IAnsibleTaskStatus { 5 | _id?: string; 6 | taskIdent: string; 7 | status: string; 8 | createdAt?: Date; 9 | updatedAt?: Date; 10 | } -------------------------------------------------------------------------------- /server/src/modules/ansible/domain/entities/ansible-task-status.interface.ts: -------------------------------------------------------------------------------- 1 | export interface IAnsibleTaskStatus { 2 | _id?: string; 3 | taskIdent: string; 4 | status: string; 5 | createdAt?: Date; 6 | updatedAt?: Date; 7 | } -------------------------------------------------------------------------------- /server/src/modules/ansible/domain/entities/ansible-task.entity.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Domain entity for an Ansible task 3 | */ 4 | export interface IAnsibleTask { 5 | _id?: string; 6 | ident: string; 7 | name?: string; 8 | cmd?: string; 9 | playbook?: string; 10 | status: string; 11 | target?: string[]; 12 | options?: Record; 13 | createdAt?: Date; 14 | updatedAt?: Date; 15 | } -------------------------------------------------------------------------------- /server/src/modules/ansible/domain/entities/ansible-task.interface.ts: -------------------------------------------------------------------------------- 1 | export interface IAnsibleTask { 2 | _id?: string; 3 | ident: string; 4 | name?: string; 5 | cmd?: string; 6 | playbook?: string; 7 | status: string; 8 | target?: string[]; 9 | options?: Record; 10 | createdAt?: Date; 11 | updatedAt?: Date; 12 | } 13 | -------------------------------------------------------------------------------- /server/src/modules/ansible/domain/repositories/ansible-task-status.repository.interface.ts: -------------------------------------------------------------------------------- 1 | import { IAnsibleTaskStatus } from '../entities/ansible-task-status.entity'; 2 | 3 | export const ANSIBLE_TASK_STATUS_REPOSITORY = 'ANSIBLE_TASK_STATUS_REPOSITORY'; 4 | 5 | export interface IAnsibleTaskStatusRepository { 6 | create(taskStatus: Partial): Promise; 7 | findByTaskIdent(taskIdent: string): Promise; 8 | deleteAllByIdent(taskIdent: string): Promise; 9 | } 10 | -------------------------------------------------------------------------------- /server/src/modules/ansible/presentation/decorators/ansible-inventory.decorator.ts: -------------------------------------------------------------------------------- 1 | import { applyDecorators } from '@nestjs/common'; 2 | import { ApiQuery } from '@nestjs/swagger'; 3 | import { ApiOperation } from '@nestjs/swagger'; 4 | 5 | export function GetInventoryDoc() { 6 | return applyDecorators( 7 | ApiOperation({ summary: 'Get Ansible inventory' }), 8 | ApiQuery({ name: 'execUuid', type: String, required: true }), 9 | ApiQuery({ name: 'target', type: String, required: false }), 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /server/src/modules/ansible/presentation/dtos/get-inventory-body.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsOptional, IsUUID } from 'class-validator'; 2 | 3 | export class GetInventoryBodyDto { 4 | @IsOptional() 5 | @IsUUID() 6 | target?: string; // Assuming target is a device UUID 7 | } 8 | -------------------------------------------------------------------------------- /server/src/modules/ansible/presentation/dtos/get-inventory-query.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsString } from 'class-validator'; 2 | 3 | export class GetInventoryQueryDto { 4 | @IsString() 5 | execUuid!: string; 6 | } 7 | -------------------------------------------------------------------------------- /server/src/modules/ansible/presentation/dtos/task-event.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsNotEmpty, IsOptional, IsString } from 'class-validator'; 2 | 3 | export class TaskEventDto { 4 | @IsNotEmpty() 5 | @IsString() 6 | runner_ident!: string; 7 | 8 | @IsOptional() 9 | @IsString() 10 | uuid?: string; 11 | 12 | @IsOptional() 13 | @IsString() 14 | stdout?: string; 15 | 16 | // Additional fields from the original payload can be added here 17 | // These are kept optional as different event types may have different payloads 18 | [key: string]: any; 19 | } 20 | -------------------------------------------------------------------------------- /server/src/modules/ansible/presentation/dtos/task-hook.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsNotEmpty, IsString } from 'class-validator'; 2 | 3 | export class TaskHookDto { 4 | @IsNotEmpty() 5 | @IsString() 6 | runner_ident!: string; 7 | 8 | @IsNotEmpty() 9 | @IsString() 10 | status!: string; 11 | } 12 | -------------------------------------------------------------------------------- /server/src/modules/ansible/presentation/interfaces/api-response.interface.ts: -------------------------------------------------------------------------------- 1 | import { Response } from 'express'; 2 | 3 | export interface IApiResponse { 4 | success: boolean; 5 | statusCode: number; 6 | message?: string; 7 | data?: any; 8 | send(res: Response): void; 9 | } 10 | 11 | export interface ISuccessResponse extends IApiResponse { 12 | data?: any; 13 | } 14 | 15 | export interface IErrorResponse extends IApiResponse { 16 | error: { 17 | code: string; 18 | message: string; 19 | details?: any; 20 | }; 21 | } -------------------------------------------------------------------------------- /server/src/modules/automations/application/services/components/triggers/abstract-trigger.component.ts: -------------------------------------------------------------------------------- 1 | import { AutomationComponent } from '../automation.component'; 2 | 3 | export abstract class AbstractTriggerComponent { 4 | public automation: AutomationComponent; 5 | 6 | constructor(automation: AutomationComponent) { 7 | this.automation = automation; 8 | } 9 | 10 | async onCall() { 11 | await this.automation.onTrigger(); 12 | } 13 | 14 | deregister() {} 15 | } 16 | -------------------------------------------------------------------------------- /server/src/modules/automations/domain/entities/automation.entity.ts: -------------------------------------------------------------------------------- 1 | import { v4 as uuidv4 } from 'uuid'; 2 | 3 | export class Automation { 4 | uuid?: string = uuidv4(); 5 | name: string = ''; 6 | automationChains: any = {}; 7 | lastExecutionTime?: Date; 8 | lastExecutionStatus?: 'success' | 'failed'; 9 | enabled: boolean = true; 10 | } 11 | -------------------------------------------------------------------------------- /server/src/modules/automations/presentation/dtos/create-automation.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsBoolean, IsNotEmpty, IsObject, IsOptional, IsString } from 'class-validator'; 2 | 3 | export class CreateAutomationDto { 4 | @IsString() 5 | @IsNotEmpty() 6 | name!: string; 7 | 8 | @IsObject() 9 | @IsNotEmpty() 10 | automationChains: any; 11 | 12 | @IsBoolean() 13 | @IsOptional() 14 | enabled: boolean = true; 15 | } 16 | -------------------------------------------------------------------------------- /server/src/modules/automations/presentation/dtos/update-automation.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsBoolean, IsNotEmpty, IsObject, IsOptional, IsString } from 'class-validator'; 2 | 3 | export class UpdateAutomationDto { 4 | @IsString() 5 | @IsNotEmpty() 6 | @IsOptional() 7 | name?: string; 8 | 9 | @IsObject() 10 | @IsNotEmpty() 11 | @IsOptional() 12 | automationChains?: any; 13 | 14 | @IsBoolean() 15 | @IsOptional() 16 | enabled?: boolean; 17 | } 18 | -------------------------------------------------------------------------------- /server/src/modules/container-stacks/domain/entities/repository-config.entity.ts: -------------------------------------------------------------------------------- 1 | import { SsmGit } from 'ssm-shared-lib'; 2 | 3 | /** 4 | * Represents the configuration for a Git repository 5 | */ 6 | export interface RepositoryConfig { 7 | uuid: string; 8 | name: string; 9 | branch: string; 10 | email: string; 11 | userName: string; 12 | accessToken: string; 13 | remoteUrl: string; 14 | gitService: SsmGit.Services; 15 | ignoreSSLErrors?: boolean; 16 | } -------------------------------------------------------------------------------- /server/src/modules/container-stacks/domain/interfaces/container-repository-component-service.interface.ts: -------------------------------------------------------------------------------- 1 | export const CONTAINER_REPOSITORY_COMPONENT_SERVICE = 'CONTAINER_REPOSITORY_COMPONENT_SERVICE'; 2 | 3 | export interface IContainerRepositoryComponentService {} 4 | -------------------------------------------------------------------------------- /server/src/modules/container-stacks/index.ts: -------------------------------------------------------------------------------- 1 | import { ContainerStacksModule } from './container-stacks.module'; 2 | import { ContainerStacksService } from './application/services/container-stacks.service'; 3 | 4 | export { ContainerStacksModule, ContainerStacksService }; -------------------------------------------------------------------------------- /server/src/modules/containers/__tests__/application/services/components/kind-mock.ts: -------------------------------------------------------------------------------- 1 | // Mock for the Kind enum 2 | export enum Kind { 3 | REGISTRY = 'registry', 4 | WATCHER = 'watcher', 5 | NETWORK = 'network', 6 | VOLUME = 'volume', 7 | CONTAINER = 'container', 8 | } -------------------------------------------------------------------------------- /server/src/modules/containers/__tests__/application/services/components/mock-component: -------------------------------------------------------------------------------- 1 | export class Component { 2 | name = 'component'; 3 | 4 | match() { 5 | return true; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /server/src/modules/containers/__tests__/application/services/components/samples/notSemver.json: -------------------------------------------------------------------------------- 1 | { 2 | "registry":"registry", 3 | "image":"organization/image", 4 | "tag":"notasemver", 5 | "versionDate":"2019-05-20T12:02:06.307Z", 6 | "architecture":"arch", 7 | "os":"os", 8 | "size":20, 9 | "isSemver":false 10 | } 11 | -------------------------------------------------------------------------------- /server/src/modules/containers/__tests__/samples/notSemver.json: -------------------------------------------------------------------------------- 1 | { 2 | "registry":"registry", 3 | "image":"organization/image", 4 | "tag":"notasemver", 5 | "versionDate":"2019-05-20T12:02:06.307Z", 6 | "architecture":"arch", 7 | "os":"os", 8 | "size":20, 9 | "isSemver":false 10 | } 11 | -------------------------------------------------------------------------------- /server/src/modules/containers/application/services/components/core/constants.ts: -------------------------------------------------------------------------------- 1 | export enum WATCHERS { 2 | DOCKER = 'docker', 3 | PROXMOX = 'proxmox', 4 | } 5 | export enum REGISTRIES { 6 | HUB = 'hub', 7 | CUSTOM = 'custom', 8 | GCR = 'gcr', 9 | GHCR = 'ghcr', 10 | QUAY = 'quay', 11 | ECR = 'ecr', 12 | GITEA = 'gitea', 13 | FORGEJO = 'forgejo', 14 | LSCR = 'lscr', 15 | GITLAB = 'gitlab', 16 | ACR = 'acr', 17 | } -------------------------------------------------------------------------------- /server/src/modules/containers/domain/components/kind.enum.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Component kind enum 3 | */ 4 | export enum Kind { 5 | WATCHER = 'watcher', 6 | REGISTRY = 'registry', 7 | UNKNOWN = 'Unknown', 8 | } 9 | -------------------------------------------------------------------------------- /server/src/modules/containers/domain/entities/container-registry.entity.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Domain entity for container registries 3 | */ 4 | export interface IContainerRegistryEntity { 5 | _id?: string; 6 | name: string; 7 | auth?: any; 8 | authScheme: any; 9 | provider: string; 10 | authSet: boolean; 11 | canAuth: boolean; 12 | canAnonymous: boolean; 13 | fullName?: string; 14 | createdAt?: Date; 15 | updatedAt?: Date; 16 | } 17 | -------------------------------------------------------------------------------- /server/src/modules/containers/domain/enums/container-health.enum.ts: -------------------------------------------------------------------------------- 1 | export enum ContainerHealth { 2 | NONE = 'none', 3 | STARTING = 'starting', 4 | HEALTHY = 'healthy', 5 | UNHEALTHY = 'unhealthy', 6 | } 7 | -------------------------------------------------------------------------------- /server/src/modules/containers/presentation/dtos/container-action.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsEnum, IsNotEmpty, IsString } from 'class-validator'; 2 | import { SsmContainer } from 'ssm-shared-lib'; 3 | 4 | /** 5 | * DTO for container actions 6 | */ 7 | export class ContainerActionDto { 8 | /** 9 | * The action to perform on the container 10 | */ 11 | @IsString() 12 | @IsNotEmpty() 13 | @IsEnum(SsmContainer.Actions) 14 | action!: SsmContainer.Actions; 15 | } -------------------------------------------------------------------------------- /server/src/modules/containers/presentation/dtos/container-logs.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsNumber, IsOptional, IsString } from 'class-validator'; 2 | import { Type } from 'class-transformer'; 3 | 4 | /** 5 | * DTO for container logs requests 6 | */ 7 | export class ContainerLogsDto { 8 | @IsString() 9 | containerId!: string; 10 | 11 | @IsOptional() 12 | @IsNumber() 13 | @Type(() => Number) 14 | from?: number; 15 | } -------------------------------------------------------------------------------- /server/src/modules/containers/presentation/dtos/create-volume.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsNotEmpty, IsObject, IsString } from 'class-validator'; 2 | 3 | /** 4 | * DTO for creating a new volume 5 | */ 6 | export class CreateVolumeDto { 7 | @IsObject() 8 | @IsNotEmpty() 9 | config!: string; 10 | 11 | @IsString() 12 | @IsNotEmpty() 13 | target!: string; 14 | } 15 | -------------------------------------------------------------------------------- /server/src/modules/diagnostic/domain/entities/diagnostic.entity.ts: -------------------------------------------------------------------------------- 1 | import { SsmDeviceDiagnostic } from 'ssm-shared-lib'; 2 | 3 | export type DiagnosticCheckType = SsmDeviceDiagnostic.Checks; 4 | 5 | export interface DiagnosticResult { 6 | success: boolean; 7 | severity: 'success' | 'warning' | 'error'; 8 | message: string; 9 | data?: any; 10 | } 11 | 12 | export interface DiagnosticReport { 13 | deviceId: string; 14 | timestamp: Date; 15 | results: Record; 16 | } 17 | -------------------------------------------------------------------------------- /server/src/modules/diagnostic/domain/interfaces/diagnostic-service.interface.ts: -------------------------------------------------------------------------------- 1 | import { IDevice, IDeviceAuth } from '../../../devices'; 2 | import { DiagnosticReport } from '../../domain/entities/diagnostic.entity'; 3 | 4 | export interface IDiagnosticService { 5 | run(device: IDevice, deviceAuth: IDeviceAuth): Promise; 6 | } 7 | -------------------------------------------------------------------------------- /server/src/modules/health/health.controller.ts: -------------------------------------------------------------------------------- 1 | import { Controller, Get } from '@nestjs/common'; 2 | import { ApiTags } from '@nestjs/swagger'; 3 | import { Public } from 'src/decorators/public.decorator'; 4 | import { HEALTH_TAG, PingDoc } from './decorators/health.decorators'; 5 | import { HealthResponseDto } from './presentation/dtos/health.dto'; 6 | 7 | @ApiTags(HEALTH_TAG) 8 | @Controller() 9 | export class HealthController { 10 | @Public() 11 | @Get('ping') 12 | @PingDoc() 13 | ping(): HealthResponseDto { 14 | return { status: 'ok' }; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /server/src/modules/health/health.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { HealthController } from './health.controller'; 3 | 4 | @Module({ 5 | controllers: [HealthController], 6 | }) 7 | export class HealthModule {} 8 | -------------------------------------------------------------------------------- /server/src/modules/health/presentation/dtos/health.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger'; 2 | 3 | export class HealthResponseDto { 4 | @ApiProperty({ 5 | description: 'The status of the health check', 6 | example: 'ok', 7 | type: String, 8 | }) 9 | status!: string; 10 | } 11 | -------------------------------------------------------------------------------- /server/src/modules/logs/domain/entities/ansible-log.entity.ts: -------------------------------------------------------------------------------- 1 | export class AnsibleLogEntity { 2 | _id?: string; 3 | ident!: string; 4 | content?: string; 5 | stdout?: string; 6 | logRunnerId?: string; 7 | createdAt?: Date; 8 | } 9 | -------------------------------------------------------------------------------- /server/src/modules/logs/domain/entities/server-log.entity.ts: -------------------------------------------------------------------------------- 1 | export class ServerLogEntity { 2 | _id?: string; 3 | level?: number; 4 | time?: Date; 5 | pid?: number; 6 | hostname?: string; 7 | context?: string; 8 | msg?: string; 9 | req?: any; 10 | res?: any; 11 | err?: any; 12 | } 13 | -------------------------------------------------------------------------------- /server/src/modules/logs/domain/repositories/server-logs-repository.interface.ts: -------------------------------------------------------------------------------- 1 | import { ServerLogEntity } from '../entities/server-log.entity'; 2 | 3 | export const SERVER_LOGS_REPOSITORY = 'IServerLogsRepository'; 4 | 5 | export interface IServerLogsRepository { 6 | findAll(): Promise; 7 | deleteAllOld(ageInDays: number): Promise; 8 | deleteAll(): Promise; 9 | } 10 | -------------------------------------------------------------------------------- /server/src/modules/logs/presentation/dtos/server-log-response.dto.ts: -------------------------------------------------------------------------------- 1 | export class ServerLogResponseDto { 2 | level?: number; 3 | time?: Date; 4 | pid?: number; 5 | hostname?: string; 6 | context?: string; 7 | msg?: string; 8 | req?: any; 9 | res?: any; 10 | err?: any; 11 | } 12 | -------------------------------------------------------------------------------- /server/src/modules/mcp/application/constants/mcp.constants.ts: -------------------------------------------------------------------------------- 1 | export const MCP_ENABLED_CACHE_KEY = 'mcp.enabled'; 2 | export const MCP_ALLOWED_PLAYBOOKS_CACHE_KEY = 'mcp.allowed_playbooks'; 3 | -------------------------------------------------------------------------------- /server/src/modules/mcp/application/dto/get-container.payload.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger'; 2 | import { IsNotEmpty, IsString } from 'class-validator'; 3 | 4 | export class GetContainerPayloadDto { 5 | @ApiProperty({ 6 | description: 'The ID or name of the container to retrieve', 7 | example: 'nginx-proxy', // Could be MongoId or Docker ID/name 8 | }) 9 | @IsString() // Keeping as string to allow Docker ID/name 10 | @IsNotEmpty() 11 | containerId!: string; 12 | } 13 | -------------------------------------------------------------------------------- /server/src/modules/mcp/application/dto/get-device.payload.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger'; 2 | import { IsNotEmpty, IsString } from 'class-validator'; 3 | 4 | export class GetDevicePayloadDto { 5 | @ApiProperty({ 6 | description: 'The UUID of the device to retrieve', 7 | example: '11111111-1111-1111-1111-111111111111', 8 | }) 9 | @IsString() 10 | @IsNotEmpty() 11 | deviceUuid!: string; 12 | } 13 | -------------------------------------------------------------------------------- /server/src/modules/mcp/application/dto/get-stats-query.payload.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsDateString, IsOptional, IsString } from 'class-validator'; 2 | 3 | export class GetStatsQueryPayloadDto { 4 | @IsOptional() 5 | @IsString() 6 | metricName?: string; 7 | 8 | @IsOptional() 9 | @IsDateString() 10 | startTime?: string; 11 | 12 | @IsOptional() 13 | @IsDateString() 14 | endTime?: string; 15 | } 16 | -------------------------------------------------------------------------------- /server/src/modules/mcp/application/dto/playbook-status.payload.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger'; 2 | import { IsNotEmpty, IsString } from 'class-validator'; 3 | 4 | export class PlaybookStatusPayloadDto { 5 | @ApiProperty({ description: 'The ID of the job', example: 123 }) 6 | @IsNotEmpty() 7 | @IsString() 8 | execId!: string; 9 | } 10 | -------------------------------------------------------------------------------- /server/src/modules/mcp/application/dto/timeseries-stats.response.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsISO8601, IsNumber } from 'class-validator'; 2 | 3 | export class TimeseriesDataPointDto { 4 | @IsISO8601() 5 | timestamp!: string; 6 | 7 | @IsNumber() 8 | value!: number; 9 | } 10 | -------------------------------------------------------------------------------- /server/src/modules/notifications/domain/entities/notification.entity.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Notification entity interface in the domain layer 3 | */ 4 | export interface Notification { 5 | id?: string; 6 | event: string; 7 | message: string; 8 | severity: 'info' | 'warning' | 'error'; 9 | seen: boolean; 10 | module: string; 11 | moduleId?: string; 12 | createdAt?: Date; 13 | updatedAt?: Date; 14 | } 15 | -------------------------------------------------------------------------------- /server/src/modules/notifications/domain/interfaces/notification-component-service.interface.ts: -------------------------------------------------------------------------------- 1 | import { OnModuleInit } from '@nestjs/common'; 2 | 3 | export const NOTIFICATION_COMPONENT_SERVICE = 'NOTIFICATION_COMPONENT_SERVICE'; 4 | 5 | /** 6 | * Interface for the Notification Component Service 7 | */ 8 | export interface INotificationComponentService extends OnModuleInit { 9 | onModuleInit(): void; 10 | } 11 | -------------------------------------------------------------------------------- /server/src/modules/notifications/domain/repositories/notification-repository.interface.ts: -------------------------------------------------------------------------------- 1 | import { Notification } from '../entities/notification.entity'; 2 | 3 | export const NOTIFICATION_REPOSITORY = 'INotificationRepository'; 4 | 5 | export interface INotificationRepository { 6 | create(notification: Partial): Promise; 7 | findAllNotSeen(): Promise; 8 | countAllNotSeen(): Promise; 9 | markAllSeen(): Promise; 10 | } -------------------------------------------------------------------------------- /server/src/modules/notifications/index.ts: -------------------------------------------------------------------------------- 1 | import { NotificationsModule } from './notifications.module'; 2 | import { Notification } from './domain/entities/notification.entity'; 3 | 4 | export { NotificationsModule }; 5 | export { Notification }; 6 | export * from './application/services/notification.service'; 7 | export * from './presentation/controllers/notification.controller'; 8 | -------------------------------------------------------------------------------- /server/src/modules/playbooks/constants.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Constants for the playbooks module 3 | */ 4 | import { SSM_DATA_PATH } from '../../config'; 5 | 6 | export const DIRECTORY_ROOT = `${SSM_DATA_PATH}/playbooks`; 7 | export const FILE_PATTERN = /\.yml$/; 8 | -------------------------------------------------------------------------------- /server/src/modules/playbooks/domain/interfaces/tree-node-service.interface.ts: -------------------------------------------------------------------------------- 1 | import { DirectoryTree } from 'ssm-shared-lib'; 2 | 3 | /** 4 | * Interface for tree node operations 5 | */ 6 | export interface ITreeNodeService { 7 | completeNode(node: DirectoryTree.ExtendedTreeNode): Promise; 8 | recursivelyFlattenTree(tree: DirectoryTree.TreeNode, depth?: number): (DirectoryTree.TreeNode | undefined)[]; 9 | recursiveTreeCompletion(tree: DirectoryTree.TreeNode, depth?: number): Promise; 10 | } 11 | 12 | export const TREE_NODE_SERVICE = 'TREE_NODE_SERVICE'; -------------------------------------------------------------------------------- /server/src/modules/remote-system-information/application/services/index.ts: -------------------------------------------------------------------------------- 1 | export * from './remote-ssh-executor.service'; -------------------------------------------------------------------------------- /server/src/modules/remote-system-information/domain/index.ts: -------------------------------------------------------------------------------- 1 | // Interfaces 2 | export * from './interfaces/remote-system-information-service.interface'; 3 | export * from './interfaces/remote-ssh-executor-service.interface'; 4 | export * from './interfaces/remote-system-information-engine-service.interface'; 5 | 6 | // Types 7 | export * from './types/remote-executor.types'; 8 | export * from './types/update.types'; 9 | -------------------------------------------------------------------------------- /server/src/modules/remote-system-information/domain/system-information/os-information/osinformation.utils.ts: -------------------------------------------------------------------------------- 1 | export function getVboxmanage() { 2 | const _windows = false; 3 | return _windows 4 | ? `"${process.env.VBOX_INSTALL_PATH || process.env.VBOX_MSI_INSTALL_PATH}\\VBoxManage.exe"` 5 | : 'vboxmanage'; 6 | } 7 | -------------------------------------------------------------------------------- /server/src/modules/remote-system-information/infrastructure/queue/constants.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Remote system information queue name 3 | */ 4 | export const REMOTE_SYSTEM_INFO_QUEUE = 'remote-system-information'; 5 | 6 | /** 7 | * Job concurrency limit 8 | */ 9 | export const JOB_CONCURRENCY = 5; 10 | -------------------------------------------------------------------------------- /server/src/modules/remote-system-information/infrastructure/queue/index.ts: -------------------------------------------------------------------------------- 1 | export * from './constants'; 2 | export * from './remote-system-information.processor'; -------------------------------------------------------------------------------- /server/src/modules/remote-system-information/infrastructure/queue/types.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/server/src/modules/remote-system-information/infrastructure/queue/types.ts -------------------------------------------------------------------------------- /server/src/modules/scheduler/domain/entities/cron.entity.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Cron entity interface in the domain layer 3 | */ 4 | export interface ICron { 5 | _id?: string; 6 | name: string; 7 | disabled?: boolean; 8 | lastExecution?: Date; 9 | expression: string; 10 | createdAt?: Date; 11 | updatedAt?: Date; 12 | } -------------------------------------------------------------------------------- /server/src/modules/scheduler/domain/repositories/cron-repository.interface.ts: -------------------------------------------------------------------------------- 1 | import { ICron } from '../entities/cron.entity'; 2 | 3 | export const CRON_REPOSITORY = 'CRON_REPOSITORY'; 4 | 5 | /** 6 | * Cron repository interface in the domain layer 7 | */ 8 | export interface ICronRepository { 9 | updateOrCreateIfNotExist(cron: ICron): Promise; 10 | updateCron(cron: ICron): Promise; 11 | findAll(): Promise; 12 | findByName(name: string): Promise; 13 | } -------------------------------------------------------------------------------- /server/src/modules/scheduler/presentation/dto/cron.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsBoolean, IsOptional, IsString } from 'class-validator'; 2 | 3 | export class CronResponseDto { 4 | @IsString() 5 | name!: string; 6 | 7 | @IsString() 8 | expression!: string; 9 | 10 | @IsOptional() 11 | @IsBoolean() 12 | disabled?: boolean; 13 | 14 | @IsOptional() 15 | lastExecution?: Date; 16 | 17 | @IsOptional() 18 | createdAt?: Date; 19 | 20 | @IsOptional() 21 | updatedAt?: Date; 22 | } -------------------------------------------------------------------------------- /server/src/modules/settings/domain/entities/setting.entity.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Setting entity interface in the domain layer 3 | */ 4 | export interface ISetting { 5 | /** 6 | * The unique key for the setting 7 | */ 8 | key: string; 9 | 10 | /** 11 | * The value of the setting 12 | */ 13 | value: string; 14 | 15 | /** 16 | * Whether the setting should only be set if it doesn't exist yet 17 | */ 18 | nx?: boolean; 19 | } -------------------------------------------------------------------------------- /server/src/modules/settings/index.ts: -------------------------------------------------------------------------------- 1 | import { ISettingsService } from './domain/interfaces/settings-service.interface'; 2 | import { SettingsModule } from './settings.module'; 3 | 4 | // Re-export the module and interfaces 5 | export { SettingsModule, ISettingsService }; 6 | -------------------------------------------------------------------------------- /server/src/modules/settings/presentation/dto/setting.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsNotEmpty, IsString } from 'class-validator'; 2 | 3 | export class SettingDto { 4 | @IsNotEmpty() 5 | @IsString() 6 | value!: string; 7 | } -------------------------------------------------------------------------------- /server/src/modules/settings/presentation/dtos/update-setting.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsNotEmpty, IsString } from 'class-validator'; 2 | 3 | /** 4 | * DTO for updating a setting 5 | */ 6 | export class UpdateSettingDto { 7 | @IsNotEmpty() 8 | @IsString() 9 | value!: string; 10 | } 11 | 12 | // For backward compatibility 13 | export type SettingDto = UpdateSettingDto; -------------------------------------------------------------------------------- /server/src/modules/settings/presentation/validators/master-node-url.validator.ts: -------------------------------------------------------------------------------- 1 | import { ValidationPipe } from '@nestjs/common'; 2 | import { IsNotEmpty, IsString, IsUrl } from 'class-validator'; 3 | 4 | export class MasterNodeUrlBodyDto { 5 | @IsNotEmpty() 6 | @IsString() 7 | @IsUrl({ require_tld: false }) 8 | value!: string; 9 | } 10 | 11 | export const MasterNodeUrlValidator = new ValidationPipe({ 12 | transform: true, 13 | whitelist: true, 14 | }); 15 | -------------------------------------------------------------------------------- /server/src/modules/sftp/index.ts: -------------------------------------------------------------------------------- 1 | // Domain exports 2 | export * from './domain/entities/sftp.entity'; 3 | 4 | // Application exports 5 | export * from './domain/interfaces/sftp-service.interface'; 6 | export * from './application/services/sftp.service'; 7 | 8 | // Infrastructure exports 9 | export * from './infrastructure/services/file-stream.service'; 10 | 11 | // Presentation exports 12 | export * from './presentation/dtos/sftp-session.dto'; 13 | export * from './presentation/gateways/sftp.gateway'; 14 | 15 | // Module export 16 | export * from './sftp.module'; 17 | -------------------------------------------------------------------------------- /server/src/modules/shell/domain/entities/shell-command.entity.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Represents a shell command in the domain layer 3 | */ 4 | export interface IShellCommand { 5 | command: string; 6 | args?: string[]; 7 | options?: Record; 8 | } -------------------------------------------------------------------------------- /server/src/modules/shell/domain/interfaces/docker-compose.interface.ts: -------------------------------------------------------------------------------- 1 | import { ShellString } from 'shelljs'; 2 | 3 | /** 4 | * Interface for Docker Compose operations in the application layer 5 | */ 6 | export interface IDockerComposeService { 7 | dockerComposeDryRun(command: string): ShellString; 8 | } 9 | -------------------------------------------------------------------------------- /server/src/modules/shell/domain/interfaces/playbook-file.interface.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Interface for Playbook file operations in the application layer 3 | */ 4 | export interface IPlaybookFileService { 5 | readPlaybook(path: string): string; 6 | editPlaybook(content: string, path: string): void; 7 | newPlaybook(path: string): void; 8 | deletePlaybook(path: string): void; 9 | testExistence(path: string): boolean; 10 | readConfigIfExists(path: string): any; 11 | } -------------------------------------------------------------------------------- /server/src/modules/smart-failure/domain/entities/failure-pattern.entity.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is deprecated. Use failure-pattern.interface.ts for interfaces. 3 | */ 4 | // (Intentionally left blank. Interfaces moved to failure-pattern.interface.ts) 5 | -------------------------------------------------------------------------------- /server/src/modules/smart-failure/domain/repositories/smart-failure.repository.interface.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Interface for Ansible logs repository 3 | */ 4 | export const SMART_FAILURE_REPOSITORY = 'ISmartFailureRepository'; 5 | 6 | export interface ISmartFailureRepository { 7 | /** 8 | * Find all logs by execution identifier 9 | * @param execId Execution ID 10 | * @returns Array of log entries or undefined if none found 11 | */ 12 | findAllByIdent(execId: string): Promise; 13 | } 14 | -------------------------------------------------------------------------------- /server/src/modules/smart-failure/index.ts: -------------------------------------------------------------------------------- 1 | export * from './smart-failure.module'; 2 | export * from './application/services/smart-failure.service'; 3 | export * from './presentation/controllers/smart-failure.controller'; 4 | export * from './domain/entities/failure-pattern.interface'; 5 | export * from './presentation/dtos/smart-failure.dto'; 6 | export * from './domain/constants'; 7 | -------------------------------------------------------------------------------- /server/src/modules/smart-failure/presentation/dtos/smart-failure.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsNotEmpty, IsUUID } from 'class-validator'; 2 | 3 | /** 4 | * DTO for analyzing smart failure request 5 | */ 6 | export class AnalyzeSmartFailureDto { 7 | /** 8 | * Execution ID of the Ansible run 9 | */ 10 | @IsUUID() 11 | @IsNotEmpty() 12 | execId!: string; 13 | } 14 | 15 | // For backward compatibility 16 | export type SmartFailureRequestDto = AnalyzeSmartFailureDto; 17 | -------------------------------------------------------------------------------- /server/src/modules/ssh/index.ts: -------------------------------------------------------------------------------- 1 | // Domain exports 2 | export * from './domain/entities/ssh.entity'; 3 | 4 | // Application exports 5 | export * from './domain/interfaces/ssh-connection-service.interface'; 6 | export * from './domain/interfaces/ssh-terminal-service.interface'; 7 | export * from './application/services/ssh-terminal.service'; 8 | 9 | 10 | // Presentation exports 11 | export * from './presentation/dtos/ssh-session.dto'; 12 | 13 | // Module export 14 | export * from './ssh.module'; -------------------------------------------------------------------------------- /server/src/modules/ssh/presentation/dtos/ssh-session.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsNotEmpty, IsNumber, IsString } from "class-validator"; 2 | 3 | export class SshSessionDto { 4 | @IsString() 5 | @IsNotEmpty() 6 | deviceUuid!: string; 7 | 8 | @IsNumber() 9 | @IsNotEmpty() 10 | rows!: number; 11 | 12 | @IsNumber() 13 | @IsNotEmpty() 14 | cols!: number; 15 | } 16 | 17 | export class ScreenResizeDto { 18 | @IsNumber() 19 | @IsNotEmpty() 20 | rows!: number; 21 | 22 | @IsNumber() 23 | @IsNotEmpty() 24 | cols!: number; 25 | } 26 | -------------------------------------------------------------------------------- /server/src/modules/statistics/domain/constants/constants.ts: -------------------------------------------------------------------------------- 1 | export const DEVICE_WENT_OFFLINE_EVENT = 'device.went.offline'; 2 | export const DEVICE_WENT_ONLINE_EVENT = 'device.went.online'; 3 | -------------------------------------------------------------------------------- /server/src/modules/statistics/domain/entities/device-downtime-event.entity.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Device Downtime Event entity interface in the domain layer 3 | */ 4 | export interface IDeviceDownTimeEvent { 5 | _id?: string; 6 | deviceId: string; 7 | finishedAt?: Date; 8 | duration?: number; 9 | createdAt?: Date; 10 | updatedAt?: Date; 11 | } -------------------------------------------------------------------------------- /server/src/modules/statistics/index.ts: -------------------------------------------------------------------------------- 1 | export * from './domain/constants/constants'; 2 | -------------------------------------------------------------------------------- /server/src/modules/telemetry/dto/telemetry-event-payload.dto.ts: -------------------------------------------------------------------------------- 1 | export interface TelemetryEventPayload { 2 | eventName: string; 3 | properties?: Record; 4 | } 5 | -------------------------------------------------------------------------------- /server/src/modules/telemetry/index.ts: -------------------------------------------------------------------------------- 1 | export * from './telemetry.module'; 2 | export * from './telemetry.service'; 3 | export { TelemetryEventPayload } from './dto/telemetry-event-payload.dto'; 4 | -------------------------------------------------------------------------------- /server/src/modules/telemetry/telemetry.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { ConfigModule } from '@nestjs/config'; 3 | import { TelemetryService } from './telemetry.service'; 4 | 5 | @Module({ 6 | imports: [ConfigModule], 7 | providers: [TelemetryService], 8 | exports: [TelemetryService], 9 | }) 10 | export class TelemetryModule {} 11 | -------------------------------------------------------------------------------- /server/src/modules/update/index.ts: -------------------------------------------------------------------------------- 1 | export * from './update.module'; 2 | export * from './services/update.service'; 3 | -------------------------------------------------------------------------------- /server/src/modules/update/update.module.ts: -------------------------------------------------------------------------------- 1 | import { HttpModule } from '@nestjs/axios'; 2 | import { Module } from '@nestjs/common'; 3 | import { ScheduleModule } from '@nestjs/schedule'; 4 | import { UpdateService } from './services/update.service'; 5 | 6 | @Module({ 7 | imports: [ScheduleModule, HttpModule], 8 | providers: [UpdateService], 9 | exports: [UpdateService], 10 | }) 11 | export class UpdateModule {} 12 | -------------------------------------------------------------------------------- /server/src/modules/users/presentation/dtos/login-response.dto.ts: -------------------------------------------------------------------------------- 1 | export class LoginResponseDto { 2 | currentAuthority?: string; 3 | } -------------------------------------------------------------------------------- /server/src/modules/users/presentation/dtos/login.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsBoolean, IsNotEmpty, IsOptional, IsString } from 'class-validator'; 2 | 3 | export class LoginDto { 4 | @IsString() 5 | @IsNotEmpty() 6 | username!: string; 7 | 8 | @IsString() 9 | @IsNotEmpty() 10 | password!: string; 11 | 12 | @IsBoolean() 13 | @IsOptional() 14 | autoLogin?: boolean; 15 | } -------------------------------------------------------------------------------- /server/src/tests/molecule/README.md: -------------------------------------------------------------------------------- 1 | # MOLECULE TESTS 2 | 3 | ## Install 4 | 5 | - Molecule 6 | - Molecule Docker 7 | - Test infra 8 | - pytest 9 | 10 | ```shell 11 | pip install -r requirements.txt 12 | ``` 13 | 14 | Create a Python venv 15 | 16 | ```shell 17 | python3 -m venv ~/venv/ansible-molecule 18 | source ~/venv/ansible-molecule/bin/activate 19 | ``` 20 | 21 | ## Execute tests 22 | ```shell 23 | cd ./server/src/tests 24 | molecule test -s 25 | ``` 26 | -------------------------------------------------------------------------------- /server/src/tests/molecule/create-docker-network/converge.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Converge 3 | hosts: all 4 | become: true 5 | 6 | - import_playbook: "../../../ansible/00000000-0000-0000-0000-000000000000/docker/_createDockerNetwork.yml" 7 | -------------------------------------------------------------------------------- /server/src/tests/molecule/default/molecule.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependency: 3 | name: galaxy 4 | 5 | platforms: 6 | - name: instance 7 | connection_options: 8 | ansible_connection: local 9 | provisioner: 10 | name: ansible 11 | playbooks: 12 | converge: run_all.yml 13 | scenario: 14 | test_sequence: 15 | - dependency 16 | - destroy 17 | - create 18 | - prepare 19 | - converge 20 | # - idempotence 21 | - verify 22 | -------------------------------------------------------------------------------- /server/src/tests/molecule/install-agent-enhanced/converge.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Converge 3 | hosts: instance 4 | become: true 5 | gather_facts: false 6 | 7 | - import_playbook: "../../../ansible/00000000-0000-0000-0000-000000000000/agent/_installAgent.yml" 8 | 9 | -------------------------------------------------------------------------------- /server/src/tests/molecule/install-agent-enhanced/destroy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Destroy 3 | hosts: localhost 4 | connection: local 5 | gather_facts: False 6 | tasks: 7 | - name: Destroy docker container 8 | community.docker.docker_container: 9 | name: instance 10 | state: absent 11 | -------------------------------------------------------------------------------- /server/src/tests/molecule/install-agent-enhanced/prepare.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Prepare 3 | hosts: instance 4 | become: true 5 | tasks: 6 | - name: Ensure Python3 is installed 7 | raw: test -e /usr/bin/python3 || (apt-get update && apt-get install -y python3 python3-pip) 8 | -------------------------------------------------------------------------------- /server/src/tests/molecule/install-agent-enhanced/requirements.yml: -------------------------------------------------------------------------------- 1 | collections: 2 | - name: community.docker 3 | version: ">=3.10.2" 4 | - name: community.general 5 | version: ">=7.0.0" 6 | source: https://galaxy.ansible.com 7 | -------------------------------------------------------------------------------- /server/src/tests/molecule/install-agent/converge.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Converge 3 | hosts: instance 4 | become: true 5 | gather_facts: false 6 | 7 | - import_playbook: "../../../ansible/00000000-0000-0000-0000-000000000000/agent/_installAgent.yml" 8 | 9 | -------------------------------------------------------------------------------- /server/src/tests/molecule/install-agent/destroy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Destroy 3 | hosts: localhost 4 | connection: local 5 | gather_facts: False 6 | tasks: 7 | - name: Destroy docker container 8 | community.docker.docker_container: 9 | name: instance 10 | state: absent 11 | -------------------------------------------------------------------------------- /server/src/tests/molecule/install-agent/prepare.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Prepare 3 | hosts: instance 4 | become: true 5 | tasks: 6 | - name: Ensure Python3 is installed 7 | raw: test -e /usr/bin/python3 || (apt-get update && apt-get install -y python3 python3-pip) 8 | -------------------------------------------------------------------------------- /server/src/tests/molecule/install-agent/requirements.yml: -------------------------------------------------------------------------------- 1 | collections: 2 | - name: community.docker 3 | version: ">=3.10.2" 4 | - name: community.general 5 | version: ">=7.0.0" 6 | source: https://galaxy.ansible.com 7 | -------------------------------------------------------------------------------- /server/src/tests/molecule/install-docker/molecule.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependency: 3 | name: shell 4 | command: "pip install pytest-testinfra" 5 | 6 | driver: 7 | name: docker 8 | platforms: 9 | - name: instance-debian 10 | image: debian:latest 11 | command: sleep infinity 12 | privileged: true 13 | ulimits: nofile:1024:2048 14 | provisioner: 15 | name: ansible 16 | playbooks: 17 | prepare: prepare.yml 18 | converge: playbook.yml 19 | verifier: 20 | name: testinfra 21 | directory: ./tests 22 | -------------------------------------------------------------------------------- /server/src/tests/molecule/install-docker/playbook.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Converge 3 | hosts: all 4 | roles: 5 | - ../../../ansible/00000000-0000-0000-0000-000000000000/agent/roles/install_docker 6 | -------------------------------------------------------------------------------- /server/src/tests/molecule/install-docker/prepare.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Prepare 3 | hosts: all 4 | become: true 5 | tasks: 6 | - name: Ensure Python3 is installed 7 | raw: test -e /usr/bin/python3 || (apt-get update && apt-get install -y python3 python3-pip) 8 | - name: Ensure required preparation (You may add other preparation tasks here) 9 | ansible.builtin.shell: echo "Preparation step complete" 10 | -------------------------------------------------------------------------------- /server/src/tests/molecule/install-docker/tests/test_default.py: -------------------------------------------------------------------------------- 1 | import os 2 | import pytest 3 | import testinfra 4 | 5 | def test_os_release_file(host): 6 | f = host.file("/etc/os-release") 7 | assert f.exists 8 | assert f.contains("Debian") 9 | 10 | def test_docker_installed(host): 11 | docker = host.package("docker-ce") 12 | assert docker.is_installed 13 | 14 | 15 | def test_docker_running_and_enabled(host): 16 | docker = host.service("docker") 17 | assert docker.is_running 18 | assert docker.is_enabled 19 | -------------------------------------------------------------------------------- /server/src/tests/molecule/install-docker/tools/install-depencencies.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | pip install pytest-testinfra 4 | -------------------------------------------------------------------------------- /server/src/tests/molecule/requirements.txt: -------------------------------------------------------------------------------- 1 | molecule 2 | molecule-plugins 3 | ansible 4 | pytest 5 | pytest-testinfra 6 | -------------------------------------------------------------------------------- /server/src/tests/molecule/upgrade-packages/Dockerfile.j2: -------------------------------------------------------------------------------- 1 | # Dockerfile.j2 2 | 3 | FROM {{ item.image }} 4 | 5 | # For Debian-based systems 6 | {% if item.image.startswith('debian') or item.image.startswith('ubuntu') %} 7 | RUN apt-get update && \ 8 | apt-get install -y python3 python3-pip sshpass sudo 9 | {% endif %} 10 | 11 | # For RHEL-based systems 12 | {% if item.image.startswith('centos') or item.image.startswith('rhel') or item.image.startswith('rockylinux') %} 13 | RUN yum update -y && \ 14 | yum install -y python3 python3-pip sshpass sudo 15 | {% endif %} 16 | -------------------------------------------------------------------------------- /server/src/tests/molecule/upgrade-packages/converge.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Converge 3 | hosts: all 4 | become: true 5 | gather_facts: false 6 | 7 | - import_playbook: "../../../ansible/00000000-0000-0000-0000-000000000000/device/_upgrade.yml" 8 | 9 | -------------------------------------------------------------------------------- /server/src/tests/molecule/upgrade-packages/requirements.yml: -------------------------------------------------------------------------------- 1 | collections: 2 | - name: community.docker 3 | version: ">=3.10.2" 4 | - name: community.general 5 | version: ">=7.0.0" 6 | source: https://galaxy.ansible.com 7 | -------------------------------------------------------------------------------- /server/src/types/AuthenticatedRequest.d.ts: -------------------------------------------------------------------------------- 1 | import SSMUser from '../data/database/model/User'; 2 | 3 | declare global { 4 | namespace Express { 5 | interface User extends SSMUser {} 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /server/src/types/semver.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'semver' { 2 | const semver: any; 3 | type SemVer = any; 4 | export { SemVer }; 5 | export = semver; 6 | } 7 | -------------------------------------------------------------------------------- /server/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": [ 4 | "node_modules", 5 | "dist", 6 | "**/*.spec.ts", 7 | "**/*.test.ts", 8 | "**/obsolete/**", 9 | "**/__tests__/**", 10 | "src/modules/common-test-helpers.ts" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /server/vitest.workspace.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "extends": "./vitest.config.ts", 4 | "name": "integration", 5 | "include": "src/__tests__/*" 6 | }, 7 | { 8 | "extends": "./vitest.config.ts", 9 | "name": "modules", 10 | "include": "src/modules/*", 11 | "exclude": ["**/*.md"] 12 | } 13 | ] 14 | -------------------------------------------------------------------------------- /shared-lib/.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | node_modules 3 | distribution 4 | -------------------------------------------------------------------------------- /shared-lib/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /shared-lib/.eslintignore: -------------------------------------------------------------------------------- 1 | /distribution/ 2 | -------------------------------------------------------------------------------- /shared-lib/.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | /node_modules 3 | /npm-debug.log* 4 | /yarn-error.log 5 | /yarn.lock 6 | 7 | # production 8 | /dist 9 | /distribution 10 | /distribution/ 11 | /distribution/* 12 | # misc 13 | .DS_Store 14 | -------------------------------------------------------------------------------- /shared-lib/.prettierignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /shared-lib/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "arrowParens": "always", 4 | "printWidth": 100, 5 | "proseWrap": "never", 6 | "endOfLine": "lf" 7 | } 8 | -------------------------------------------------------------------------------- /shared-lib/src/enums/agent.ts: -------------------------------------------------------------------------------- 1 | export enum InstallMethods { 2 | NODE = 'node', 3 | NODE_ENHANCED_PLAYBOOK = 'node_enhanced_playbook', 4 | DOCKER = 'docker', 5 | LESS = 'less' 6 | } 7 | -------------------------------------------------------------------------------- /shared-lib/src/enums/alert.ts: -------------------------------------------------------------------------------- 1 | export enum AlertType { 2 | ERROR = 'error', 3 | SUCCESS = 'success', 4 | WARNING = 'warning', 5 | INFO = 'info', 6 | } 7 | -------------------------------------------------------------------------------- /shared-lib/src/enums/container.ts: -------------------------------------------------------------------------------- 1 | export enum ContainerTypes { 2 | DOCKER = 'docker', 3 | PROXMOX = 'proxmox', 4 | LXC = 'lxc', 5 | } 6 | 7 | export enum Actions { 8 | PAUSE = 'pause', 9 | START = 'start', 10 | RESTART = 'restart', 11 | KILL = 'kill', 12 | STOP = 'stop' 13 | } 14 | 15 | export enum VolumeActions { 16 | BACKUP = 'backup' 17 | } 18 | 19 | export enum VolumeBackupMode { 20 | FILE_SYSTEM = 'filesystem', 21 | BROWSER = 'browser', 22 | } 23 | -------------------------------------------------------------------------------- /shared-lib/src/enums/diagnostic.ts: -------------------------------------------------------------------------------- 1 | export enum Checks { 2 | SSH_CONNECT = 'SSH_CONNECT', 3 | SSH_DOCKER_CONNECT = 'SSH_DOCKER_CONNECT', 4 | DOCKER_SOCKET = 'DOCKER_SOCKET', 5 | DISK_SPACE = 'DISK_SPACE', 6 | CPU_MEMORY_INFO= 'CPU_MEMORY_INFO' 7 | } 8 | -------------------------------------------------------------------------------- /shared-lib/src/enums/git.ts: -------------------------------------------------------------------------------- 1 | export enum Services { 2 | Github = 'github', 3 | GitLab = 'gitlab', 4 | Bitbucket = 'bitbucket', 5 | AzureRepos = 'azure-repos', 6 | Gitea = 'gitea' 7 | } 8 | -------------------------------------------------------------------------------- /shared-lib/src/enums/proxmox.ts: -------------------------------------------------------------------------------- 1 | export enum RemoteConnectionMethod { 2 | SSH = 'ssh', 3 | HTTP = 'http', 4 | } 5 | 6 | export enum ConnectionMethod { 7 | USER_PWD = 'userPwd', 8 | TOKENS = 'tokens', 9 | } 10 | 11 | export enum ContainerType { 12 | LXC = 'lxc', 13 | QEMU = 'qemu' 14 | } 15 | -------------------------------------------------------------------------------- /shared-lib/src/enums/repositories.ts: -------------------------------------------------------------------------------- 1 | export enum RepositoryType { 2 | LOCAL = 'local', 3 | GIT = 'git', 4 | } 5 | -------------------------------------------------------------------------------- /shared-lib/src/enums/stats.ts: -------------------------------------------------------------------------------- 1 | export enum ContainerStatsType { 2 | CPU = "container_cpu_usage", 3 | MEM = "container_memory_usage" 4 | } 5 | export enum DeviceStatsType { 6 | CPU = "cpu_usage", 7 | MEM_USED = "memory_usage", 8 | MEM_FREE = "memory_free", 9 | CONTAINERS = "containers", 10 | DISK_USED = "storage_usage", 11 | DISK_FREE = "storage_free" 12 | } 13 | -------------------------------------------------------------------------------- /shared-lib/src/enums/status.ts: -------------------------------------------------------------------------------- 1 | export enum DeviceStatus { 2 | REGISTERING = 0, 3 | ONLINE = 1, 4 | OFFLINE = 2, 5 | UNMANAGED = 3, 6 | } 7 | 8 | export enum ContainerStatus { 9 | RUNNING = 'running', 10 | PAUSED = 'paused', 11 | UNREACHABLE = 'unreachable', 12 | STOPPED = 'stopped' 13 | } 14 | -------------------------------------------------------------------------------- /shared-lib/src/types/tree.ts: -------------------------------------------------------------------------------- 1 | export enum CONSTANTS { 2 | DIRECTORY = 'directory', 3 | FILE = 'file', 4 | } 5 | 6 | export type TreeNode = { 7 | path: string; 8 | name: string; 9 | isSymbolicLink?: boolean; 10 | extension?: string; 11 | type?: CONSTANTS.DIRECTORY | CONSTANTS.FILE; 12 | children?: (TreeNode | ExtendedTreeNode | null)[]; 13 | size?: number; 14 | }; 15 | 16 | export type ExtendedTreeNode = TreeNode & { 17 | uuid?: string; 18 | extraVars?: any; 19 | custom?: boolean; 20 | }; 21 | -------------------------------------------------------------------------------- /shared-lib/src/validation/index.ts: -------------------------------------------------------------------------------- 1 | export const playbookNameRegexp = '^[0-9a-zA-Z\\-]{0,100}$'; 2 | export const privateKeyRegexp = /\s*(\bBEGIN\b).*(PRIVATE KEY\b)\s*/ 3 | -------------------------------------------------------------------------------- /shared-lib/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2016", 4 | "module": "commonjs", 5 | "forceConsistentCasingInFileNames": true, 6 | "strict": true, 7 | "skipLibCheck": true, 8 | "esModuleInterop": true, 9 | "declaration": true, 10 | "outDir": "./distribution" 11 | }, 12 | "include": ["src/**/*"] 13 | } 14 | -------------------------------------------------------------------------------- /site/apps/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | --- 4 | 5 | 9 | 10 |
Want to add your service here ? Contact me
11 | 12 | 13 | -------------------------------------------------------------------------------- /site/components/ComponentInfoGrid.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /site/components/DecisionTree.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 18 | 19 | -------------------------------------------------------------------------------- /site/components/FeatureGrid.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | 11 | 19 | -------------------------------------------------------------------------------- /site/docs/credits.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: FeatureGuideLayout 3 | title: "Credits" 4 | icon: "✨" 5 | time: "5 min read" 6 | signetColor: '#00bcd4' 7 | credits: true 8 | --- 9 | 10 | # Credits / Special thanks 11 | 12 | Parts of SSM code came from: 13 | - [Dockerode](https://github.com/apocas/dockerode/blob/master/LICENSE) 14 | - [What's up Docker?](https://github.com/fmartinou/whats-up-docker/blob/master/LICENSE) 15 | - [Ant Design Pro Preview](https://github.com/ant-design/v2.preview.pro.ant.design/blob/v2/LICENSE) 16 | 17 | -------------------------------------------------------------------------------- /site/docs/user-guides/containers/qemu-lxc-containers.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: FeatureGuideLayout 3 | title: "QEMU / LXC Containers" 4 | icon: "📦" # Package/container icon 5 | time: "5 min read" 6 | signetColor: '#27ae60' 7 | nextStep: 8 | icon: "➡️" 9 | title: "Next Topic" 10 | description: "Continue to the next relevant section." 11 | link: "#" 12 | credits: true 13 | --- 14 | -------------------------------------------------------------------------------- /site/netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | # only build on netlify if there are any change in docs 3 | ignore = "git diff --quiet 'HEAD^' HEAD ." 4 | -------------------------------------------------------------------------------- /site/public/cec74183c37dd72ce1e162506a2655ae.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/cec74183c37dd72ce1e162506a2655ae.txt -------------------------------------------------------------------------------- /site/public/images/1746729748-add-unmanaged-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/1746729748-add-unmanaged-2.png -------------------------------------------------------------------------------- /site/public/images/about-goal.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /site/public/images/about-simple.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/about-simple.gif -------------------------------------------------------------------------------- /site/public/images/about-square-star.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /site/public/images/add-device-add-device-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/add-device-add-device-1.png -------------------------------------------------------------------------------- /site/public/images/add-device-add-device-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/add-device-add-device-2.png -------------------------------------------------------------------------------- /site/public/images/add-device-add-device-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/add-device-add-device-3.png -------------------------------------------------------------------------------- /site/public/images/add-device-add-device-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/add-device-add-device-4.png -------------------------------------------------------------------------------- /site/public/images/add-device-add-device-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/add-device-add-device-5.png -------------------------------------------------------------------------------- /site/public/images/add-device-add-device-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/add-device-add-device-6.png -------------------------------------------------------------------------------- /site/public/images/add-device-add-device-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/add-device-add-device-7.png -------------------------------------------------------------------------------- /site/public/images/add-unmanaged-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/add-unmanaged-1.png -------------------------------------------------------------------------------- /site/public/images/add-unmanaged-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/add-unmanaged-2.png -------------------------------------------------------------------------------- /site/public/images/add-unmanaged-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/add-unmanaged-3.png -------------------------------------------------------------------------------- /site/public/images/ansible.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /site/public/images/automations-add-automation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/automations-add-automation.gif -------------------------------------------------------------------------------- /site/public/images/automations-automation-logs.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/automations-automation-logs.gif -------------------------------------------------------------------------------- /site/public/images/automations-automation-model-diagram.svg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/automations-automation-model-diagram.svg -------------------------------------------------------------------------------- /site/public/images/automations-setup-cron.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/automations-setup-cron.gif -------------------------------------------------------------------------------- /site/public/images/compose-add-remote-options-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/compose-add-remote-options-2.png -------------------------------------------------------------------------------- /site/public/images/compose-compose-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/compose-compose-1.png -------------------------------------------------------------------------------- /site/public/images/compose-compose-build-1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/compose-compose-build-1.gif -------------------------------------------------------------------------------- /site/public/images/compose-compose-build-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/compose-compose-build-2.png -------------------------------------------------------------------------------- /site/public/images/compose-compose-switch.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/compose-compose-switch.gif -------------------------------------------------------------------------------- /site/public/images/containers-container-model-diagram.svg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/containers-container-model-diagram.svg -------------------------------------------------------------------------------- /site/public/images/delete-device-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/delete-device-1.png -------------------------------------------------------------------------------- /site/public/images/device-architecture.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Device Architecture Diagram (Placeholder) 5 | 6 | 7 | -------------------------------------------------------------------------------- /site/public/images/device-configuration-device-configuration-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/device-configuration-device-configuration-1.png -------------------------------------------------------------------------------- /site/public/images/device-configuration-device-configuration-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/device-configuration-device-configuration-2.png -------------------------------------------------------------------------------- /site/public/images/device-configuration-device-configuration-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/device-configuration-device-configuration-3.png -------------------------------------------------------------------------------- /site/public/images/device-configuration-device-configuration-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/device-configuration-device-configuration-4.png -------------------------------------------------------------------------------- /site/public/images/device-configuration-device-configuration-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/device-configuration-device-configuration-5.png -------------------------------------------------------------------------------- /site/public/images/device-configuration-diagnostic-diagnostic-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/device-configuration-diagnostic-diagnostic-1.png -------------------------------------------------------------------------------- /site/public/images/device-configuration-docker-docker-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/device-configuration-docker-docker-1.png -------------------------------------------------------------------------------- /site/public/images/device-configuration-proxmox-proxmox-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/device-configuration-proxmox-proxmox-1.png -------------------------------------------------------------------------------- /site/public/images/device-configuration-ssh-advanced-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/device-configuration-ssh-advanced-1.png -------------------------------------------------------------------------------- /site/public/images/devices.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/devices.png -------------------------------------------------------------------------------- /site/public/images/diagrams-concept-diagram.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Concept Diagram (Placeholder) 5 | 6 | 7 | -------------------------------------------------------------------------------- /site/public/images/exec-playbook-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/exec-playbook-1.png -------------------------------------------------------------------------------- /site/public/images/exec-playbook-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/exec-playbook-2.png -------------------------------------------------------------------------------- /site/public/images/exec-playbook-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/exec-playbook-3.png -------------------------------------------------------------------------------- /site/public/images/exec-playbook-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/exec-playbook-4.png -------------------------------------------------------------------------------- /site/public/images/exec-playbook-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/exec-playbook-5.png -------------------------------------------------------------------------------- /site/public/images/exec-playbook-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/exec-playbook-6.png -------------------------------------------------------------------------------- /site/public/images/first-time-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/first-time-1.png -------------------------------------------------------------------------------- /site/public/images/first-time-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/first-time-2.png -------------------------------------------------------------------------------- /site/public/images/first-time-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/first-time-3.png -------------------------------------------------------------------------------- /site/public/images/home-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/home-dashboard.png -------------------------------------------------------------------------------- /site/public/images/home-device-info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/home-device-info.png -------------------------------------------------------------------------------- /site/public/images/home-devices.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/home-devices.png -------------------------------------------------------------------------------- /site/public/images/home-library-filled.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /site/public/images/home-new-device.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/home-new-device.png -------------------------------------------------------------------------------- /site/public/images/home-playbook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/home-playbook.png -------------------------------------------------------------------------------- /site/public/images/home-registries.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/home-registries.png -------------------------------------------------------------------------------- /site/public/images/home-security.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /site/public/images/home-services.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/home-services.png -------------------------------------------------------------------------------- /site/public/images/home-stacks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/home-stacks.png -------------------------------------------------------------------------------- /site/public/images/home-store.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/home-store.png -------------------------------------------------------------------------------- /site/public/images/install-proxmox-install-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/install-proxmox-install-1.png -------------------------------------------------------------------------------- /site/public/images/install-proxmox-install-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/install-proxmox-install-2.png -------------------------------------------------------------------------------- /site/public/images/install-proxmox-install-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/install-proxmox-install-3.png -------------------------------------------------------------------------------- /site/public/images/install-proxmox-install-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/install-proxmox-install-4.png -------------------------------------------------------------------------------- /site/public/images/install-proxmox-shell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/install-proxmox-shell.png -------------------------------------------------------------------------------- /site/public/images/install-update.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/install-update.png -------------------------------------------------------------------------------- /site/public/images/inventory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/inventory.png -------------------------------------------------------------------------------- /site/public/images/playbooks-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/playbooks-1.png -------------------------------------------------------------------------------- /site/public/images/playbooks-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/playbooks-2.png -------------------------------------------------------------------------------- /site/public/images/playbooks-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/playbooks-3.png -------------------------------------------------------------------------------- /site/public/images/playbooks-add-file.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/playbooks-add-file.gif -------------------------------------------------------------------------------- /site/public/images/playbooks-add-local.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/playbooks-add-local.gif -------------------------------------------------------------------------------- /site/public/images/playbooks-add-remote-options.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/playbooks-add-remote-options.png -------------------------------------------------------------------------------- /site/public/images/playbooks-add-remote.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/playbooks-add-remote.gif -------------------------------------------------------------------------------- /site/public/images/playbooks-delete-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/playbooks-delete-repo.png -------------------------------------------------------------------------------- /site/public/images/playbooks-edit-playbook.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/playbooks-edit-playbook.gif -------------------------------------------------------------------------------- /site/public/images/playbooks-git.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /site/public/images/playbooks-manual-sync.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/playbooks-manual-sync.gif -------------------------------------------------------------------------------- /site/public/images/playbooks-playbook-model-diagram.svg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/playbooks-playbook-model-diagram.svg -------------------------------------------------------------------------------- /site/public/images/playbooks-playbooks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/playbooks-playbooks.png -------------------------------------------------------------------------------- /site/public/images/playbooks-remote-dropdown.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/playbooks-remote-dropdown.gif -------------------------------------------------------------------------------- /site/public/images/proxmox-install-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/proxmox-install-1.png -------------------------------------------------------------------------------- /site/public/images/proxmox-install-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/proxmox-install-2.png -------------------------------------------------------------------------------- /site/public/images/proxmox-install-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/proxmox-install-3.png -------------------------------------------------------------------------------- /site/public/images/proxmox-install-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/proxmox-install-4.png -------------------------------------------------------------------------------- /site/public/images/proxmox-shell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/proxmox-shell.png -------------------------------------------------------------------------------- /site/public/images/registries-acr-acr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-acr-acr.png -------------------------------------------------------------------------------- /site/public/images/registries-acr-acr_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-acr-acr_01.png -------------------------------------------------------------------------------- /site/public/images/registries-acr-acr_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-acr-acr_02.png -------------------------------------------------------------------------------- /site/public/images/registries-acr-acr_03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-acr-acr_03.png -------------------------------------------------------------------------------- /site/public/images/registries-custom-custom-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-custom-custom-1.png -------------------------------------------------------------------------------- /site/public/images/registries-custom-custom-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-custom-custom-2.png -------------------------------------------------------------------------------- /site/public/images/registries-custom-custom-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-custom-custom-3.png -------------------------------------------------------------------------------- /site/public/images/registries-ecr-ecr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-ecr-ecr.png -------------------------------------------------------------------------------- /site/public/images/registries-ecr-ecr_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-ecr-ecr_01.png -------------------------------------------------------------------------------- /site/public/images/registries-ecr-ecr_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-ecr-ecr_02.png -------------------------------------------------------------------------------- /site/public/images/registries-ecr-ecr_03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-ecr-ecr_03.png -------------------------------------------------------------------------------- /site/public/images/registries-forgejo-forgejo-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-forgejo-forgejo-1.png -------------------------------------------------------------------------------- /site/public/images/registries-forgejo-forgejo-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-forgejo-forgejo-2.png -------------------------------------------------------------------------------- /site/public/images/registries-gcr-gcr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-gcr-gcr.png -------------------------------------------------------------------------------- /site/public/images/registries-ghcr-ghcr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-ghcr-ghcr.png -------------------------------------------------------------------------------- /site/public/images/registries-ghcr-ghcr_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-ghcr-ghcr_01.png -------------------------------------------------------------------------------- /site/public/images/registries-ghcr-ghcr_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-ghcr-ghcr_02.png -------------------------------------------------------------------------------- /site/public/images/registries-gitea-gitea.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-gitea-gitea.png -------------------------------------------------------------------------------- /site/public/images/registries-gitlab-gitlab-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-gitlab-gitlab-1.png -------------------------------------------------------------------------------- /site/public/images/registries-gitlab-gitlab-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-gitlab-gitlab-2.png -------------------------------------------------------------------------------- /site/public/images/registries-gitlab-gitlab_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-gitlab-gitlab_01.png -------------------------------------------------------------------------------- /site/public/images/registries-gitlab-gitlab_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-gitlab-gitlab_02.png -------------------------------------------------------------------------------- /site/public/images/registries-hub-hub-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-hub-hub-1.png -------------------------------------------------------------------------------- /site/public/images/registries-hub-hub-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-hub-hub-2.png -------------------------------------------------------------------------------- /site/public/images/registries-hub-hub-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-hub-hub-3.png -------------------------------------------------------------------------------- /site/public/images/registries-hub-hub_login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-hub-hub_login.png -------------------------------------------------------------------------------- /site/public/images/registries-hub-hub_token.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-hub-hub_token.png -------------------------------------------------------------------------------- /site/public/images/registries-lscr-lscr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-lscr-lscr.png -------------------------------------------------------------------------------- /site/public/images/registries-lscr-lscr_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-lscr-lscr_01.png -------------------------------------------------------------------------------- /site/public/images/registries-lscr-lscr_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-lscr-lscr_02.png -------------------------------------------------------------------------------- /site/public/images/registries-quay-quay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-quay-quay.png -------------------------------------------------------------------------------- /site/public/images/registries-quay-quay_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-quay-quay_01.png -------------------------------------------------------------------------------- /site/public/images/registries-quay-quay_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-quay-quay_02.png -------------------------------------------------------------------------------- /site/public/images/registries-registries-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-registries-1.png -------------------------------------------------------------------------------- /site/public/images/registries-registries-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-registries-2.png -------------------------------------------------------------------------------- /site/public/images/registries-registries-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-registries-3.png -------------------------------------------------------------------------------- /site/public/images/registries-registries-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries-registries-4.png -------------------------------------------------------------------------------- /site/public/images/registries.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/registries.png -------------------------------------------------------------------------------- /site/public/images/schema.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/schema.png -------------------------------------------------------------------------------- /site/public/images/security-model-diagram.svg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/security-model-diagram.svg -------------------------------------------------------------------------------- /site/public/images/services-deploy-conf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/services-deploy-conf.png -------------------------------------------------------------------------------- /site/public/images/services-deploy-store.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/services-deploy-store.png -------------------------------------------------------------------------------- /site/public/images/services-services-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/services-services-1.png -------------------------------------------------------------------------------- /site/public/images/services-services-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/services-services-2.png -------------------------------------------------------------------------------- /site/public/images/services-services-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/services-services-3.png -------------------------------------------------------------------------------- /site/public/images/services-services-overview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/services-services-overview.gif -------------------------------------------------------------------------------- /site/public/images/services.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/services.png -------------------------------------------------------------------------------- /site/public/images/settings-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/settings-1.png -------------------------------------------------------------------------------- /site/public/images/settings-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/settings-2.png -------------------------------------------------------------------------------- /site/public/images/settings-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/settings-3.png -------------------------------------------------------------------------------- /site/public/images/squirrel-community.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/squirrel-community.png -------------------------------------------------------------------------------- /site/public/images/squirrel-concepts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/squirrel-concepts.png -------------------------------------------------------------------------------- /site/public/images/squirrel-developper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/squirrel-developper.png -------------------------------------------------------------------------------- /site/public/images/squirrel-reference.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/squirrel-reference.png -------------------------------------------------------------------------------- /site/public/images/squirrels-squirrel-ai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/squirrels-squirrel-ai.png -------------------------------------------------------------------------------- /site/public/images/squirrels-squirrel-troubleshoot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/squirrels-squirrel-troubleshoot.png -------------------------------------------------------------------------------- /site/public/images/technical-guide-ansible-ansible-configuration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/technical-guide-ansible-ansible-configuration.png -------------------------------------------------------------------------------- /site/public/images/technical-guide-ansible-ansible-galaxy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/technical-guide-ansible-ansible-galaxy.gif -------------------------------------------------------------------------------- /site/public/images/technical-guide-ansible-become-method.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/technical-guide-ansible-become-method.png -------------------------------------------------------------------------------- /site/public/images/technical-guide-docker-docker-advanced-connection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/technical-guide-docker-docker-advanced-connection.png -------------------------------------------------------------------------------- /site/public/images/technical-guide-docker-docker-certs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/technical-guide-docker-docker-certs.png -------------------------------------------------------------------------------- /site/public/images/technical-guide-docker-docker-options.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/technical-guide-docker-docker-options.png -------------------------------------------------------------------------------- /site/public/images/technical-guide-ssh-ssh-key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/technical-guide-ssh-ssh-key.png -------------------------------------------------------------------------------- /site/public/images/technical-guide-ssh-ssh-password.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/technical-guide-ssh-ssh-password.png -------------------------------------------------------------------------------- /site/public/images/technical-guide-troubleshoot-connection-method.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquirrelCorporation/SquirrelServersManager/6dc6d5ded743f7d4a04a4aea7de98b8cb3576730/site/public/images/technical-guide-troubleshoot-connection-method.png -------------------------------------------------------------------------------- /tests/test-device/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.8' 2 | services: 3 | ssh_dind_test: 4 | build: 5 | context: . 6 | container_name: ssh_dind_test_server 7 | ports: 8 | - "2222:22" # Map container port 22 to host port 2222 9 | volumes: 10 | - /var/run/docker.sock:/var/run/docker.sock # Mount host Docker socket 11 | # Add privileged: true ONLY if running actual DinD (not just mounting socket) 12 | # privileged: true 13 | restart: unless-stopped --------------------------------------------------------------------------------