mirror of
https://github.com/lorsanstand/HomeOps-Hub.git
synced 2026-06-19 13:15:17 +03:00
Merge pull request #6 from lorsanstand/feat/register-agent
Feat/register agent
This commit is contained in:
+6
@@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="SqlNoDataSourceInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
</profile>
|
||||
</component>
|
||||
@@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AutoImportSettings">
|
||||
<option name="autoReloadType" value="ALL" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="abe4019d-78ad-4b09-9aa4-c503fa264179" name="Changes" comment="" />
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="FileTemplateManagerImpl">
|
||||
<option name="RECENT_TEMPLATES">
|
||||
<list>
|
||||
<option value="Go File" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="GOROOT" url="file:///usr/lib/go" />
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="ProjectColorInfo">{
|
||||
"associatedIndex": 6
|
||||
}</component>
|
||||
<component name="ProjectId" id="3Bz7LjOuV8KsTCrmtXpgkPdosIV" />
|
||||
<component name="ProjectViewState">
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent"><![CDATA[{
|
||||
"keyToString": {
|
||||
"DefaultGoTemplateProperty": "Go File",
|
||||
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
||||
"RunOnceActivity.GoLinterPluginOnboardingV2": "true",
|
||||
"RunOnceActivity.GoLinterPluginStorageMigration": "true",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
|
||||
"RunOnceActivity.git.unshallow": "true",
|
||||
"RunOnceActivity.go.analysis.ui.options.defaults": "true",
|
||||
"RunOnceActivity.go.formatter.settings.were.checked": "true",
|
||||
"RunOnceActivity.go.modules.go.list.on.any.changes.was.set": "true",
|
||||
"RunOnceActivity.typescript.service.memoryLimit.init": "true",
|
||||
"git-widget-placeholder": "feat/register-agent",
|
||||
"go.sdk.automatically.set": "true",
|
||||
"last_opened_file_path": "/home/lorsan/projects/HomeOps-Hub",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
"nodejs_package_manager_path": "npm"
|
||||
}
|
||||
}]]></component>
|
||||
<component name="SharedIndexes">
|
||||
<attachedChunks>
|
||||
<set>
|
||||
<option value="bundled-gosdk-72a9cf600ed8-dfa3e7267ae0-org.jetbrains.plugins.go.sharedIndexes.bundled-GO-253.30387.193" />
|
||||
<option value="bundled-js-predefined-d6986cc7102b-9b0f141eb926-JavaScript-GO-253.30387.193" />
|
||||
</set>
|
||||
</attachedChunks>
|
||||
</component>
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="Default task">
|
||||
<changelist id="abe4019d-78ad-4b09-9aa4-c503fa264179" name="Changes" comment="" />
|
||||
<created>1775479991162</created>
|
||||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1775479991162</updated>
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
<option name="version" value="3" />
|
||||
</component>
|
||||
</project>
|
||||
+5
-2
@@ -1,8 +1,11 @@
|
||||
package main
|
||||
|
||||
import "github.com/lorsanstand/HomeOps-Hub/internal/hub/app"
|
||||
import "github.com/lorsanstand/HomeOps-Hub/internal/agent/app"
|
||||
|
||||
func main() {
|
||||
start := app.NewApp()
|
||||
start, err := app.NewApp()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
start.Run()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
services:
|
||||
postgres-db:
|
||||
image: postgres:latest
|
||||
volumes:
|
||||
- pgdata:/var/lib/postgresql
|
||||
environment:
|
||||
POSTGRES_DB: "${DB_NAME}"
|
||||
POSTGRES_USER: "${DB_USER}"
|
||||
POSTGRES_PASSWORD: "${DB_PASS}"
|
||||
networks:
|
||||
- homeops-dev
|
||||
ports:
|
||||
- "${DB_PORT}:5432"
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U ${DB_USER}"]
|
||||
interval: 5s
|
||||
retries: 5
|
||||
restart: always
|
||||
|
||||
volumes:
|
||||
pgdata:
|
||||
|
||||
networks:
|
||||
homeops-dev:
|
||||
@@ -4,8 +4,9 @@ go 1.26.1
|
||||
|
||||
require (
|
||||
github.com/docker/docker v28.5.2+incompatible
|
||||
github.com/golang-migrate/migrate/v4 v4.19.1
|
||||
github.com/ilyakaznacheev/cleanenv v1.5.0
|
||||
github.com/moby/moby v28.5.2+incompatible
|
||||
github.com/jackc/pgx/v5 v5.9.1
|
||||
github.com/rs/zerolog v1.35.0
|
||||
google.golang.org/grpc v1.80.0
|
||||
google.golang.org/protobuf v1.36.11
|
||||
@@ -14,7 +15,7 @@ require (
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.2.1 // indirect
|
||||
github.com/Microsoft/go-winio v0.4.21 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/containerd/errdefs v1.0.0 // indirect
|
||||
github.com/containerd/errdefs/pkg v0.3.0 // indirect
|
||||
@@ -25,7 +26,11 @@ require (
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
||||
github.com/joho/godotenv v1.5.1 // indirect
|
||||
github.com/lib/pq v1.10.9 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||
@@ -42,6 +47,7 @@ require (
|
||||
go.opentelemetry.io/otel/metric v1.43.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.43.0 // indirect
|
||||
golang.org/x/net v0.52.0 // indirect
|
||||
golang.org/x/sync v0.20.0 // indirect
|
||||
golang.org/x/sys v0.42.0 // indirect
|
||||
golang.org/x/text v0.35.0 // indirect
|
||||
golang.org/x/time v0.15.0 // indirect
|
||||
|
||||
@@ -2,8 +2,8 @@ github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEK
|
||||
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
|
||||
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/Microsoft/go-winio v0.4.21 h1:+6mVbXh4wPzUrl1COX9A+ZCvEpYsOBZ6/+kwDnvLyro=
|
||||
github.com/Microsoft/go-winio v0.4.21/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=
|
||||
github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
@@ -14,8 +14,11 @@ github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151X
|
||||
github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=
|
||||
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
|
||||
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dhui/dktest v0.4.6 h1:+DPKyScKSEp3VLtbMDHcUq6V5Lm5zfZZVb0Sk7Ahom4=
|
||||
github.com/dhui/dktest v0.4.6/go.mod h1:JHTSYDtKkvFNFHJKqCzVzqXecyv+tKt8EzceOmQOgbU=
|
||||
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/docker/docker v28.5.2+incompatible h1:DBX0Y0zAjZbSrm1uzOkdr1onVghKaftjlSWt4AFexzM=
|
||||
@@ -31,6 +34,8 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/golang-migrate/migrate/v4 v4.19.1 h1:OCyb44lFuQfYXYLx1SCxPZQGU7mcaZ7gH9yH4jSFbBA=
|
||||
github.com/golang-migrate/migrate/v4 v4.19.1/go.mod h1:CTcgfjxhaUtsLipnLoQRWCrjYXycRz/g5+RWDuYgPrE=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
@@ -41,20 +46,28 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c=
|
||||
github.com/ilyakaznacheev/cleanenv v1.5.0 h1:0VNZXggJE2OYdXE87bfSSwGxeiGt9moSR2lOrsHHvr4=
|
||||
github.com/ilyakaznacheev/cleanenv v1.5.0/go.mod h1:a5aDzaJrLCQZsazHol1w8InnDcOX0OColm64SlIi6gk=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgx/v5 v5.9.1 h1:uwrxJXBnx76nyISkhr33kQLlUqjv7et7b9FjCen/tdc=
|
||||
github.com/jackc/pgx/v5 v5.9.1/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4=
|
||||
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
||||
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
||||
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
||||
github.com/moby/moby v28.5.2+incompatible h1:hIn6qcenb3JY1E3STwqEbBvJ8bha+u1LpqjX4CBvNCk=
|
||||
github.com/moby/moby v28.5.2+incompatible/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc=
|
||||
github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw=
|
||||
github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs=
|
||||
github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU=
|
||||
@@ -69,16 +82,18 @@ github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQ
|
||||
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||
github.com/rs/zerolog v1.35.0 h1:VD0ykx7HMiMJytqINBsKcbLS+BJ4WYjz+05us+LRTdI=
|
||||
github.com/rs/zerolog v1.35.0/go.mod h1:EjML9kdfa/RMA7h/6z6pYmq1ykOuA8/mjWaEvGI+jcw=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
||||
@@ -103,8 +118,8 @@ go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpu
|
||||
go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk=
|
||||
golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0=
|
||||
golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
|
||||
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
|
||||
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
@@ -114,6 +129,7 @@ golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
|
||||
golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
|
||||
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
|
||||
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
|
||||
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9 h1:VPWxll4HlMw1Vs/qXtN7BvhZqsS9cdAittCNvVENElA=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9/go.mod h1:7QBABkRtR8z+TEnmXTqIqwJLlzrZKVfAUm7tY3yGv0M=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9 h1:m8qni9SQFH0tJc1X0vmnpw/0t+AImlSvp30sEupozUg=
|
||||
@@ -125,6 +141,7 @@ google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=
|
||||
|
||||
@@ -1,37 +1,53 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
standartlog "log"
|
||||
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/agent/rpc"
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/agent/service/agent_service"
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/agent/service/collector"
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/agent/service/docker_service"
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/agent/utils/config_yaml"
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/agent/utils/settings"
|
||||
log2 "github.com/lorsanstand/HomeOps-Hub/internal/shared/log"
|
||||
"github.com/rs/zerolog"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
)
|
||||
|
||||
type App struct {
|
||||
log zerolog.Logger
|
||||
cfg *config_yaml.AgentConfig
|
||||
hubConn *rpc.Connection
|
||||
log zerolog.Logger
|
||||
cfg *config_yaml.AgentConfig
|
||||
settings *settings.Settings
|
||||
hubConn *rpc.Connection
|
||||
}
|
||||
|
||||
func NewApp() *App {
|
||||
func NewApp() (*App, error) {
|
||||
|
||||
cfg, err := config_yaml.NewConfig()
|
||||
if err != nil {
|
||||
standartlog.Fatalf("failed get config: %v", err)
|
||||
standartlog.Fatalf("failed to get config: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log := log2.NewLogger(cfg)
|
||||
log = log.With().Str("component", "agent.app").Logger()
|
||||
|
||||
return &App{cfg: cfg, log: log}
|
||||
sett, err := settings.ReadSettings(cfg.SettingsPath)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("failed to get settings")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &App{cfg: cfg, log: log, settings: sett}, nil
|
||||
}
|
||||
|
||||
func (a *App) Run() {
|
||||
GRPCConn, err := grpc.NewClient(a.cfg.GetGRPCAddress())
|
||||
ctx := context.Background()
|
||||
|
||||
GRPCConn, err := grpc.NewClient(a.cfg.GetGRPCAddress(), grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
if err != nil {
|
||||
a.log.Error().Err(err).Msg("failed to get hub connections")
|
||||
return
|
||||
@@ -50,7 +66,8 @@ func (a *App) Run() {
|
||||
DockerService = docker_service.NewDockerService(DockerClient, a.log)
|
||||
}
|
||||
|
||||
Collector := collector.NewCollector(DockerService, a.log)
|
||||
collect := collector.NewCollector(DockerService, a.log)
|
||||
|
||||
Collector.GatherInfoSystem()
|
||||
agent := agent_service.NewAgentService(collect, conn, a.settings, a.cfg, a.log)
|
||||
agent.RegisterAgentConn(ctx)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"context"
|
||||
|
||||
pb "github.com/lorsanstand/HomeOps-Hub/api/gen/homeops"
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/agent/domain"
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/domain"
|
||||
"github.com/rs/zerolog"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
@@ -32,8 +32,8 @@ func (c *Connection) Hub() pb.HubClient {
|
||||
return c.hub
|
||||
}
|
||||
|
||||
func (c *Connection) RegisterAgent(ctx context.Context, RegisterData domain.RegisterAgentData) (domain.RegisterAgentDataResponse, error) {
|
||||
ResponseData, err := c.Hub().RegisterAgent(ctx, new(toAgentRegisterRequest(RegisterData)))
|
||||
func (c *Connection) RegisterAgent(ctx context.Context, RegisterData domain.RegisterAgentRequest) (domain.RegisterAgentResponse, error) {
|
||||
ResponseData, err := c.Hub().RegisterAgent(ctx, new(domain.ToGRPCAgentRequest(RegisterData)))
|
||||
c.log.Info().Msg("register agent")
|
||||
return toAgentRegisterDataResponse(ResponseData), err
|
||||
return domain.ToDomainAgentResponse(ResponseData), err
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
package rpc
|
||||
|
||||
import (
|
||||
pb "github.com/lorsanstand/HomeOps-Hub/api/gen/homeops"
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/agent/domain"
|
||||
)
|
||||
|
||||
func toAgentRegisterRequest(request domain.RegisterAgentData) pb.RegisterAgentRequest {
|
||||
return pb.RegisterAgentRequest{
|
||||
AgentId: request.AgentId,
|
||||
AgentName: request.AgentName,
|
||||
Host: &pb.HostInfo{
|
||||
Hostname: request.Host.Hostname,
|
||||
Arch: request.Host.Arch,
|
||||
System: request.Host.System,
|
||||
},
|
||||
Version: request.AgentVersion,
|
||||
Capability: toGRPCCapability(request.Capabilities),
|
||||
}
|
||||
}
|
||||
|
||||
func toGRPCCapability(caps []domain.Capability) []*pb.Capability {
|
||||
var capability []*pb.Capability
|
||||
for _, capi := range caps {
|
||||
capability = append(capability, &pb.Capability{
|
||||
Name: capi.Name,
|
||||
Available: capi.Available,
|
||||
Version: capi.Version,
|
||||
Reason: capi.Reason,
|
||||
})
|
||||
}
|
||||
return capability
|
||||
}
|
||||
|
||||
func toAgentRegisterDataResponse(response *pb.RegisterAgentResponse) domain.RegisterAgentDataResponse {
|
||||
return domain.RegisterAgentDataResponse{
|
||||
AgentID: response.AgentId,
|
||||
Heartbeat: int(response.HeartbeatIntervalSecond),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package agent_service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/agent/utils/config_yaml"
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/agent/utils/settings"
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/domain"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
const AgentVersion = "0.0"
|
||||
|
||||
type Collector interface {
|
||||
GatherInfoSystem() (domain.HostInfo, []domain.Capability)
|
||||
}
|
||||
|
||||
type HubConnection interface {
|
||||
RegisterAgent(ctx context.Context, RegisterData domain.RegisterAgentRequest) (domain.RegisterAgentResponse, error)
|
||||
}
|
||||
|
||||
type AgentService struct {
|
||||
collect Collector
|
||||
conn HubConnection
|
||||
log zerolog.Logger
|
||||
cfg *config_yaml.AgentConfig
|
||||
heartBeat int
|
||||
settings *settings.Settings
|
||||
}
|
||||
|
||||
func NewAgentService(
|
||||
collector Collector,
|
||||
conn HubConnection,
|
||||
settings *settings.Settings,
|
||||
cfg *config_yaml.AgentConfig,
|
||||
logger zerolog.Logger,
|
||||
) *AgentService {
|
||||
logger = logger.With().Str("component", "agent.service.agent_serivce").Logger()
|
||||
|
||||
return &AgentService{collect: collector, conn: conn, cfg: cfg, log: logger, settings: settings}
|
||||
}
|
||||
|
||||
func (a *AgentService) RegisterAgentConn(ctx context.Context) {
|
||||
info, caps := a.collect.GatherInfoSystem()
|
||||
AgentID := a.settings.AgentID
|
||||
AgentName := a.cfg.AppName
|
||||
AgentData := domain.RegisterAgentRequest{AgentId: AgentID, AgentName: AgentName, Host: info, Capabilities: caps, AgentVersion: AgentVersion}
|
||||
|
||||
data, err := a.conn.RegisterAgent(ctx, AgentData)
|
||||
if err != nil {
|
||||
a.log.Error().Err(err).Msg("failed register agent")
|
||||
return
|
||||
}
|
||||
|
||||
if err = a.settings.Insert(settings.Settings{AgentID: data.AgentID}); err != nil {
|
||||
a.log.Warn().Err(err).Msg("failed to save agent id")
|
||||
}
|
||||
fmt.Println(data)
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package agent_service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/domain"
|
||||
)
|
||||
|
||||
type CollectorMock struct {
|
||||
host domain.HostInfo
|
||||
caps []domain.Capability
|
||||
}
|
||||
|
||||
func (c *CollectorMock) GatherInfoSystem() (domain.HostInfo, []domain.Capability) {
|
||||
return c.host, c.caps
|
||||
}
|
||||
|
||||
type ConnectionMock struct {
|
||||
regAgentErr error
|
||||
regResp domain.RegisterAgentResponse
|
||||
}
|
||||
|
||||
func (c *ConnectionMock) RegisterAgent(ctx context.Context, RegisterData domain.RegisterAgentRequest) (domain.RegisterAgentResponse, error) {
|
||||
return c.regResp, c.regAgentErr
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"os"
|
||||
"runtime"
|
||||
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/agent/domain"
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/domain"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package docker_service
|
||||
|
||||
import "github.com/lorsanstand/HomeOps-Hub/internal/agent/domain"
|
||||
import (
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/domain"
|
||||
)
|
||||
|
||||
type BadDocker struct {
|
||||
reason string
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/agent/domain"
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/domain"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
@@ -14,11 +14,12 @@ type AgentConfig struct {
|
||||
Host string `yaml:"host"`
|
||||
Port int `yaml:"port"`
|
||||
} `yaml:"hub"`
|
||||
LogLevel string `yaml:"log_level"`
|
||||
LogLevel string `yaml:"log_level"`
|
||||
SettingsPath string `yaml:"settings_path"`
|
||||
}
|
||||
|
||||
func NewConfig() (*AgentConfig, error) {
|
||||
yamlFile, err := os.ReadFile("config.yaml")
|
||||
yamlFile, err := os.ReadFile("agent.dev.yaml")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed open file: %v", err)
|
||||
}
|
||||
@@ -41,7 +42,7 @@ func (c *AgentConfig) GetLogLevel() zerolog.Level {
|
||||
}
|
||||
|
||||
func (c *AgentConfig) GetMode() string {
|
||||
return "PROD"
|
||||
return "DEV"
|
||||
}
|
||||
|
||||
func (c *AgentConfig) GetGRPCAddress() string {
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
package settings
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type Settings struct {
|
||||
AgentID string `json:"agent_id"`
|
||||
path string
|
||||
}
|
||||
|
||||
func ReadSettings(path string) (*Settings, error) {
|
||||
if path == "" {
|
||||
homeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
path = filepath.Join(homeDir, ".config", "homeops")
|
||||
}
|
||||
|
||||
err := os.Mkdir(path, 0755)
|
||||
if err != nil {
|
||||
if !errors.Is(err, os.ErrExist) {
|
||||
return nil, err
|
||||
}
|
||||
err = nil
|
||||
}
|
||||
|
||||
settingsPath := filepath.Join(path, "settings.json")
|
||||
var settings Settings
|
||||
|
||||
file, err := os.Open(settingsPath)
|
||||
if err != nil {
|
||||
if !errors.Is(err, os.ErrNotExist) {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
defer file.Close()
|
||||
err = json.NewDecoder(file).Decode(&settings)
|
||||
if err != nil && !errors.Is(err, io.EOF) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
settings.path = settingsPath
|
||||
|
||||
return &settings, nil
|
||||
}
|
||||
|
||||
func (s *Settings) Insert(sett Settings) error {
|
||||
file, err := os.OpenFile(s.path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
if err = json.NewEncoder(file).Encode(sett); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package domain
|
||||
|
||||
type RegisterAgentData struct {
|
||||
type RegisterAgentRequest struct {
|
||||
AgentId string
|
||||
AgentName string
|
||||
AgentVersion string
|
||||
@@ -21,7 +21,7 @@ type Capability struct {
|
||||
Reason string
|
||||
}
|
||||
|
||||
type RegisterAgentDataResponse struct {
|
||||
type RegisterAgentResponse struct {
|
||||
Heartbeat int
|
||||
AgentID string
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package domain
|
||||
|
||||
import (
|
||||
pb "github.com/lorsanstand/HomeOps-Hub/api/gen/homeops"
|
||||
)
|
||||
|
||||
func ToDomainAgentRequest(request *pb.RegisterAgentRequest) RegisterAgentRequest {
|
||||
if request == nil {
|
||||
return RegisterAgentRequest{}
|
||||
}
|
||||
|
||||
return RegisterAgentRequest{
|
||||
AgentId: request.AgentId,
|
||||
AgentName: request.AgentName,
|
||||
Host: HostInfo{
|
||||
System: request.Host.System,
|
||||
Hostname: request.Host.Hostname,
|
||||
Arch: request.Host.Arch,
|
||||
},
|
||||
Capabilities: ToDomainCapabilities(request.Capability),
|
||||
}
|
||||
}
|
||||
|
||||
func ToDomainAgentResponse(response *pb.RegisterAgentResponse) RegisterAgentResponse {
|
||||
if response == nil {
|
||||
return RegisterAgentResponse{}
|
||||
}
|
||||
|
||||
return RegisterAgentResponse{
|
||||
AgentID: response.AgentId,
|
||||
Heartbeat: int(response.HeartbeatIntervalSecond),
|
||||
}
|
||||
}
|
||||
|
||||
func ToDomainCapabilities(capability []*pb.Capability) []Capability {
|
||||
var caps []Capability
|
||||
|
||||
for _, capa := range capability {
|
||||
if capa == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
caps = append(caps, Capability{
|
||||
Name: capa.Name,
|
||||
Version: capa.Version,
|
||||
Reason: capa.Reason,
|
||||
Available: capa.Available,
|
||||
})
|
||||
}
|
||||
|
||||
return caps
|
||||
}
|
||||
|
||||
func ToGRPCAgentRequest(request RegisterAgentRequest) pb.RegisterAgentRequest {
|
||||
return pb.RegisterAgentRequest{
|
||||
AgentId: request.AgentId,
|
||||
AgentName: request.AgentName,
|
||||
Host: &pb.HostInfo{
|
||||
Hostname: request.Host.Hostname,
|
||||
Arch: request.Host.Arch,
|
||||
System: request.Host.System,
|
||||
},
|
||||
Version: request.AgentVersion,
|
||||
Capability: ToGRPCCapability(request.Capabilities),
|
||||
}
|
||||
}
|
||||
|
||||
func ToGRPCAgentResponse(response RegisterAgentResponse) *pb.RegisterAgentResponse {
|
||||
return &pb.RegisterAgentResponse{AgentId: response.AgentID, HeartbeatIntervalSecond: int64(response.Heartbeat)}
|
||||
}
|
||||
|
||||
func ToGRPCCapability(caps []Capability) []*pb.Capability {
|
||||
var capability []*pb.Capability
|
||||
for _, capi := range caps {
|
||||
capability = append(capability, &pb.Capability{
|
||||
Name: capi.Name,
|
||||
Available: capi.Available,
|
||||
Version: capi.Version,
|
||||
Reason: capi.Reason,
|
||||
})
|
||||
}
|
||||
return capability
|
||||
}
|
||||
+58
-11
@@ -1,20 +1,26 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
standartlog "log"
|
||||
"net"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
hubdir "github.com/lorsanstand/HomeOps-Hub/internal/hub"
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/hub/migrator"
|
||||
grpcserv "github.com/lorsanstand/HomeOps-Hub/internal/hub/rpc"
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/hub/service/hub_service"
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/hub/store"
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/shared/config"
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/shared/log"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
type App struct {
|
||||
cfg *config.Config
|
||||
log zerolog.Logger
|
||||
server *grpcserv.HubHandler
|
||||
cfg *config.Config
|
||||
log zerolog.Logger
|
||||
}
|
||||
|
||||
func NewApp() *App {
|
||||
@@ -25,29 +31,70 @@ func NewApp() *App {
|
||||
|
||||
logger := log.NewLogger(cfg)
|
||||
|
||||
server := grpcserv.NewHubHandler(logger)
|
||||
|
||||
return &App{cfg: cfg, log: logger, server: server}
|
||||
return &App{cfg: cfg, log: logger}
|
||||
}
|
||||
|
||||
func (a *App) Run() {
|
||||
err := a.hubServe()
|
||||
ctx := context.Background()
|
||||
a.log.Info().Str("host", a.cfg.DBHost).Int("port", a.cfg.DBPort).Msg("connecting to database")
|
||||
migratePGConn, err := sql.Open("pgx", a.cfg.GetURLPostgres())
|
||||
if err != nil {
|
||||
a.log.Error().Err(err).Msg("failed start server")
|
||||
a.log.Error().Err(err).Msg("failed to connect to the database for migrations")
|
||||
return
|
||||
}
|
||||
defer migratePGConn.Close()
|
||||
|
||||
mgrt, err := migrator.NewMigrator(hubdir.MigrationsFS, "migrations")
|
||||
if err != nil {
|
||||
a.log.Error().Err(err).Msg("failed to create migrator")
|
||||
return
|
||||
}
|
||||
|
||||
a.log.Info().Msg("applying database migrations")
|
||||
if err = mgrt.ApplyMigrations(migratePGConn); err != nil {
|
||||
a.log.Error().Err(err).Msg("migrations failed to apply")
|
||||
return
|
||||
}
|
||||
a.log.Info().Msg("migrations applied successfully")
|
||||
migratePGConn.Close()
|
||||
|
||||
a.log.Info().Msg("creating database connection pool")
|
||||
pool, err := pgxpool.New(ctx, a.cfg.GetURLPostgres())
|
||||
if err != nil {
|
||||
a.log.Error().Err(err).Msg("failed to create database connection pool")
|
||||
return
|
||||
}
|
||||
defer pool.Close()
|
||||
a.log.Info().Msg("database connection pool created")
|
||||
|
||||
hubStore := store.NewHubStore(pool)
|
||||
hubService := hub_service.NewHubService(hubStore, a.log)
|
||||
|
||||
a.log.Info().Msg("starting hub service")
|
||||
err = a.hubServe(hubService)
|
||||
if err != nil {
|
||||
a.log.Error().Err(err).Msg("hub service failed to start")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (a *App) hubServe() error {
|
||||
func (a *App) hubServe(hubService *hub_service.HubService) error {
|
||||
address := fmt.Sprintf("0.0.0.0:%v", a.cfg.Port)
|
||||
a.log.Info().Str("address", "http://"+address).Msg("start GRPC server")
|
||||
a.log.Info().Str("address", address).Msg("starting gRPC server")
|
||||
|
||||
server := grpcserv.NewHubHandler(hubService, a.log)
|
||||
|
||||
lis, err := net.Listen("tcp", address)
|
||||
if err != nil {
|
||||
a.log.Error().Err(err).Str("address", address).Msg("failed to listen on address")
|
||||
return err
|
||||
}
|
||||
a.log.Info().Str("address", address).Msg("listening on address")
|
||||
|
||||
err = a.server.GrpcServer.Serve(lis)
|
||||
a.log.Info().Msg("gRPC server is running")
|
||||
err = server.GrpcServer.Serve(lis)
|
||||
if err != nil {
|
||||
a.log.Error().Err(err).Msg("gRPC server error")
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package domain
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/domain"
|
||||
)
|
||||
|
||||
type CreateAgentModel struct {
|
||||
AgentID string
|
||||
AgentName string
|
||||
Architecture string
|
||||
System string
|
||||
Hostname string
|
||||
Version string
|
||||
Capabilities []domain.Capability
|
||||
}
|
||||
|
||||
type AgentModel struct {
|
||||
ID int
|
||||
AgentID string
|
||||
AgentName string
|
||||
Architecture string
|
||||
System string
|
||||
Hostname string
|
||||
Version string
|
||||
Capabilities []domain.Capability
|
||||
RegisteredAt time.Time
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package hub
|
||||
|
||||
import "embed"
|
||||
|
||||
//go:embed migrations/*.sql
|
||||
var MigrationsFS embed.FS
|
||||
@@ -0,0 +1,4 @@
|
||||
DROP INDEX idx_agent_id_id;
|
||||
DROP INDEX idx_agent_id;
|
||||
|
||||
DROP TABLE agents IF EXISTS agents;
|
||||
@@ -0,0 +1,14 @@
|
||||
CREATE TABLE agents (
|
||||
id SERIAL PRIMARY KEY,
|
||||
agent_id VARCHAR(32) UNIQUE NOT NULL,
|
||||
agent_name VARCHAR(255),
|
||||
architecture VARCHAR(10) NOT NULL,
|
||||
system VARCHAR(10) NOT NULL,
|
||||
hostname VARCHAR(100) NOT NULL,
|
||||
version VARCHAR(10) NOT NULL,
|
||||
capabilities JSON,
|
||||
registered_at timestamp without time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX idx_agent_id ON agents (id);
|
||||
CREATE UNIQUE INDEX idx_agent_id_id On agents (agent_id)
|
||||
@@ -0,0 +1,46 @@
|
||||
package migrator
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"embed"
|
||||
"errors"
|
||||
"fmt"
|
||||
_ "github.com/jackc/pgx/v5/stdlib"
|
||||
|
||||
"github.com/golang-migrate/migrate/v4"
|
||||
"github.com/golang-migrate/migrate/v4/database/postgres"
|
||||
"github.com/golang-migrate/migrate/v4/source"
|
||||
"github.com/golang-migrate/migrate/v4/source/iofs"
|
||||
)
|
||||
|
||||
type Migrator struct {
|
||||
srcDriver source.Driver
|
||||
}
|
||||
|
||||
func NewMigrator(sqlFiles embed.FS, dirname string) (*Migrator, error) {
|
||||
d, err := iofs.New(sqlFiles, dirname)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to initialize migration driver: %w", err)
|
||||
}
|
||||
return &Migrator{srcDriver: d}, nil
|
||||
}
|
||||
|
||||
func (m *Migrator) ApplyMigrations(db *sql.DB) error {
|
||||
driver, err := postgres.WithInstance(db, &postgres.Config{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to create db instance: %w", err)
|
||||
}
|
||||
|
||||
migrator, err := migrate.NewWithInstance("migration_embeded_sql_files", m.srcDriver, "psql_db", driver)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to create migration: %w", err)
|
||||
}
|
||||
|
||||
defer migrator.Close()
|
||||
|
||||
if err = migrator.Up(); err != nil && !errors.Is(err, migrate.ErrNoChange) {
|
||||
return fmt.Errorf("unable to apply migrations: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -4,19 +4,25 @@ import (
|
||||
"context"
|
||||
|
||||
pb "github.com/lorsanstand/HomeOps-Hub/api/gen/homeops"
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/domain"
|
||||
"github.com/rs/zerolog"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/protobuf/types/known/emptypb"
|
||||
)
|
||||
|
||||
type HubService interface {
|
||||
RegisterAgent(ctx context.Context, data domain.RegisterAgentRequest) (domain.RegisterAgentResponse, error)
|
||||
}
|
||||
|
||||
type HubHandler struct {
|
||||
pb.UnimplementedHubServer
|
||||
log zerolog.Logger
|
||||
GrpcServer *grpc.Server
|
||||
hub HubService
|
||||
}
|
||||
|
||||
func NewHubHandler(logger zerolog.Logger) *HubHandler {
|
||||
hub := &HubHandler{log: logger}
|
||||
func NewHubHandler(HubServ HubService, logger zerolog.Logger) *HubHandler {
|
||||
hub := &HubHandler{log: logger, hub: HubServ}
|
||||
|
||||
grpcServer := grpc.NewServer()
|
||||
pb.RegisterHubServer(grpcServer, hub)
|
||||
@@ -27,6 +33,18 @@ func NewHubHandler(logger zerolog.Logger) *HubHandler {
|
||||
}
|
||||
|
||||
func (h *HubHandler) Ping(ctx context.Context, _ *emptypb.Empty) (*pb.PongResponse, error) {
|
||||
h.log.Info().Msg("pong request")
|
||||
h.log.Debug().Msg("ping request received")
|
||||
return &pb.PongResponse{Pong: "Pong"}, nil
|
||||
}
|
||||
|
||||
func (h *HubHandler) RegisterAgent(ctx context.Context, request *pb.RegisterAgentRequest) (*pb.RegisterAgentResponse, error) {
|
||||
h.log.Debug().Str("agentId", request.AgentId).Str("agentName", request.AgentName).Msg("register agent request received")
|
||||
data := domain.ToDomainAgentRequest(request)
|
||||
resp, err := h.hub.RegisterAgent(ctx, data)
|
||||
if err != nil {
|
||||
h.log.Error().Err(err).Str("agentId", request.AgentId).Msg("register agent request failed")
|
||||
return domain.ToGRPCAgentResponse(resp), err
|
||||
}
|
||||
h.log.Debug().Str("agentId", resp.AgentID).Msg("register agent request completed")
|
||||
return domain.ToGRPCAgentResponse(resp), nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
package hub_service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/domain"
|
||||
domainHub "github.com/lorsanstand/HomeOps-Hub/internal/hub/domain"
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/hub/utils/hasher"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
type Store interface {
|
||||
NewAgent(ctx context.Context, agent domainHub.CreateAgentModel) error
|
||||
GetAgentByAgentID(ctx context.Context, AgentID string) (domainHub.AgentModel, error)
|
||||
UpdateAgentByID(ctx context.Context, ID int, updateAgent domainHub.CreateAgentModel) error
|
||||
}
|
||||
|
||||
type HubService struct {
|
||||
store Store
|
||||
log zerolog.Logger
|
||||
}
|
||||
|
||||
func NewHubService(store Store, logger zerolog.Logger) *HubService {
|
||||
return &HubService{log: logger, store: store}
|
||||
}
|
||||
|
||||
func (h *HubService) RegisterAgent(ctx context.Context, data domain.RegisterAgentRequest) (domain.RegisterAgentResponse, error) {
|
||||
h.log.Debug().Str("agentId", data.AgentId).Str("agentName", data.AgentName).Msg("started registering agent")
|
||||
agent, err := h.store.GetAgentByAgentID(ctx, data.AgentId)
|
||||
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
||||
h.log.Error().Err(err).Str("agentId", data.AgentId).Msg("failed to get agent from database")
|
||||
return domain.RegisterAgentResponse{}, fmt.Errorf("failed select agent to db: %w", err)
|
||||
}
|
||||
|
||||
if data.AgentId != "" && !errors.Is(err, sql.ErrNoRows) {
|
||||
h.log.Debug().Str("agentId", agent.AgentID).Str("agentName", data.AgentName).Msg("agent exists, updating")
|
||||
|
||||
data.AgentId = agent.AgentID
|
||||
|
||||
agentStore := toCreateAgentModel(data)
|
||||
|
||||
if err := h.store.UpdateAgentByID(ctx, agent.ID, agentStore); err != nil {
|
||||
h.log.Error().Err(err).Str("agentId", agent.AgentID).Msg("failed to update agent in database")
|
||||
return domain.RegisterAgentResponse{}, err
|
||||
}
|
||||
h.log.Info().Str("agentId", agent.AgentID).Msg("agent updated successfully")
|
||||
return domain.RegisterAgentResponse{AgentID: agent.AgentID, Heartbeat: 5}, nil
|
||||
}
|
||||
|
||||
AgentID, err := hasher.MakeID(data.Host, data.AgentName)
|
||||
if err != nil {
|
||||
h.log.Error().Err(err).Str("agentName", data.AgentName).Str("hostname", data.Host.Hostname).Msg("failed to generate agent id")
|
||||
return domain.RegisterAgentResponse{}, err
|
||||
}
|
||||
|
||||
data.AgentId = AgentID
|
||||
|
||||
agentStore := toCreateAgentModel(data)
|
||||
|
||||
if err := h.store.NewAgent(ctx, agentStore); err != nil {
|
||||
h.log.Error().Err(err).Str("agentId", AgentID).Str("agentName", data.AgentName).Msg("failed to create new agent in database")
|
||||
return domain.RegisterAgentResponse{}, err
|
||||
}
|
||||
|
||||
h.log.Info().Str("agentId", AgentID).Str("agentName", data.AgentName).Str("hostname", data.Host.Hostname).Msg("agent registered successfully")
|
||||
return domain.RegisterAgentResponse{AgentID: AgentID, Heartbeat: 5}, nil
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package hub_service
|
||||
|
||||
import (
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/domain"
|
||||
domainHub "github.com/lorsanstand/HomeOps-Hub/internal/hub/domain"
|
||||
)
|
||||
|
||||
func toCreateAgentModel(agent domain.RegisterAgentRequest) domainHub.CreateAgentModel {
|
||||
return domainHub.CreateAgentModel{
|
||||
AgentID: agent.AgentId,
|
||||
AgentName: agent.AgentName,
|
||||
Architecture: agent.Host.Arch,
|
||||
System: agent.Host.System,
|
||||
Hostname: agent.Host.Hostname,
|
||||
Version: agent.AgentVersion,
|
||||
Capabilities: agent.Capabilities,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/domain"
|
||||
domainHub "github.com/lorsanstand/HomeOps-Hub/internal/hub/domain"
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/hub/store/sqlc/gen"
|
||||
)
|
||||
|
||||
func toDBAgent(agent domainHub.CreateAgentModel) gen.CreateAgentParams {
|
||||
return gen.CreateAgentParams{
|
||||
AgentID: agent.AgentID,
|
||||
AgentName: &agent.AgentName,
|
||||
Architecture: agent.Architecture,
|
||||
System: agent.System,
|
||||
Hostname: agent.Hostname,
|
||||
Version: agent.Version,
|
||||
Capabilities: toJsonCapabilities(agent.Capabilities),
|
||||
}
|
||||
}
|
||||
|
||||
func toUpdateDBAgent(agent domainHub.CreateAgentModel) gen.UpdateAgentByIDParams {
|
||||
return gen.UpdateAgentByIDParams{
|
||||
AgentID: agent.AgentID,
|
||||
AgentName: &agent.AgentName,
|
||||
Architecture: agent.Architecture,
|
||||
System: agent.System,
|
||||
Hostname: agent.Hostname,
|
||||
Version: agent.Version,
|
||||
Capabilities: toJsonCapabilities(agent.Capabilities),
|
||||
}
|
||||
}
|
||||
|
||||
func toJsonCapabilities(caps []domain.Capability) []byte {
|
||||
data, err := json.Marshal(caps)
|
||||
if err != nil {
|
||||
// Note: Error is silently handled - consider logging in production
|
||||
return []byte{}
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
func toAgentModel(dbAgent gen.Agent) domainHub.AgentModel {
|
||||
var dbAgentName string
|
||||
if dbAgent.AgentName != nil {
|
||||
dbAgentName = *dbAgent.AgentName
|
||||
}
|
||||
|
||||
return domainHub.AgentModel{
|
||||
ID: int(dbAgent.ID),
|
||||
AgentID: dbAgent.AgentID,
|
||||
AgentName: dbAgentName,
|
||||
Architecture: dbAgent.Architecture,
|
||||
System: dbAgent.System,
|
||||
Hostname: dbAgent.Hostname,
|
||||
Capabilities: toDomainCapabilities(dbAgent.Capabilities),
|
||||
}
|
||||
}
|
||||
|
||||
func toDomainCapabilities(caps []byte) []domain.Capability {
|
||||
var capabilities []domain.Capability
|
||||
err := json.Unmarshal(caps, &capabilities)
|
||||
if err != nil {
|
||||
// Note: Error is silently handled - consider logging in production
|
||||
return []domain.Capability{}
|
||||
}
|
||||
return capabilities
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.30.0
|
||||
// source: agent.sql
|
||||
|
||||
package gen
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
const createAgent = `-- name: CreateAgent :exec
|
||||
INSERT INTO agents (agent_id, agent_name, architecture, system, hostname, version, capabilities)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
||||
`
|
||||
|
||||
type CreateAgentParams struct {
|
||||
AgentID string
|
||||
AgentName *string
|
||||
Architecture string
|
||||
System string
|
||||
Hostname string
|
||||
Version string
|
||||
Capabilities []byte
|
||||
}
|
||||
|
||||
func (q *Queries) CreateAgent(ctx context.Context, arg CreateAgentParams) error {
|
||||
_, err := q.db.Exec(ctx, createAgent,
|
||||
arg.AgentID,
|
||||
arg.AgentName,
|
||||
arg.Architecture,
|
||||
arg.System,
|
||||
arg.Hostname,
|
||||
arg.Version,
|
||||
arg.Capabilities,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
const getAgentByAgentID = `-- name: GetAgentByAgentID :one
|
||||
SELECT id, agent_id, agent_name, architecture, system, hostname, version, capabilities, registered_at from agents
|
||||
WHERE agent_id=$1
|
||||
`
|
||||
|
||||
func (q *Queries) GetAgentByAgentID(ctx context.Context, agentID string) (Agent, error) {
|
||||
row := q.db.QueryRow(ctx, getAgentByAgentID, agentID)
|
||||
var i Agent
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.AgentID,
|
||||
&i.AgentName,
|
||||
&i.Architecture,
|
||||
&i.System,
|
||||
&i.Hostname,
|
||||
&i.Version,
|
||||
&i.Capabilities,
|
||||
&i.RegisteredAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getAgentByID = `-- name: GetAgentByID :one
|
||||
SELECT id, agent_id, agent_name, architecture, system, hostname, version, capabilities, registered_at from agents
|
||||
WHERE id=$1
|
||||
`
|
||||
|
||||
func (q *Queries) GetAgentByID(ctx context.Context, id int32) (Agent, error) {
|
||||
row := q.db.QueryRow(ctx, getAgentByID, id)
|
||||
var i Agent
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.AgentID,
|
||||
&i.AgentName,
|
||||
&i.Architecture,
|
||||
&i.System,
|
||||
&i.Hostname,
|
||||
&i.Version,
|
||||
&i.Capabilities,
|
||||
&i.RegisteredAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const updateAgentByID = `-- name: UpdateAgentByID :exec
|
||||
UPDATE agents
|
||||
SET agent_id=$1, agent_name=$2, architecture=$3, system=$4, hostname=$5, version=$6, capabilities=$7
|
||||
WHERE id=$8
|
||||
`
|
||||
|
||||
type UpdateAgentByIDParams struct {
|
||||
AgentID string
|
||||
AgentName *string
|
||||
Architecture string
|
||||
System string
|
||||
Hostname string
|
||||
Version string
|
||||
Capabilities []byte
|
||||
ID int32
|
||||
}
|
||||
|
||||
func (q *Queries) UpdateAgentByID(ctx context.Context, arg UpdateAgentByIDParams) error {
|
||||
_, err := q.db.Exec(ctx, updateAgentByID,
|
||||
arg.AgentID,
|
||||
arg.AgentName,
|
||||
arg.Architecture,
|
||||
arg.System,
|
||||
arg.Hostname,
|
||||
arg.Version,
|
||||
arg.Capabilities,
|
||||
arg.ID,
|
||||
)
|
||||
return err
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.30.0
|
||||
|
||||
package gen
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgconn"
|
||||
)
|
||||
|
||||
type DBTX interface {
|
||||
Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error)
|
||||
Query(context.Context, string, ...interface{}) (pgx.Rows, error)
|
||||
QueryRow(context.Context, string, ...interface{}) pgx.Row
|
||||
}
|
||||
|
||||
func New(db DBTX) *Queries {
|
||||
return &Queries{db: db}
|
||||
}
|
||||
|
||||
type Queries struct {
|
||||
db DBTX
|
||||
}
|
||||
|
||||
func (q *Queries) WithTx(tx pgx.Tx) *Queries {
|
||||
return &Queries{
|
||||
db: tx,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.30.0
|
||||
|
||||
package gen
|
||||
|
||||
import (
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
type Agent struct {
|
||||
ID int32
|
||||
AgentID string
|
||||
AgentName *string
|
||||
Architecture string
|
||||
System string
|
||||
Hostname string
|
||||
Version string
|
||||
Capabilities []byte
|
||||
RegisteredAt pgtype.Timestamp
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
-- name: CreateAgent :exec
|
||||
INSERT INTO agents (agent_id, agent_name, architecture, system, hostname, version, capabilities)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7);
|
||||
|
||||
-- name: GetAgentByID :one
|
||||
SELECT * from agents
|
||||
WHERE id=$1;
|
||||
|
||||
-- name: GetAgentByAgentID :one
|
||||
SELECT * from agents
|
||||
WHERE agent_id=$1;
|
||||
|
||||
-- name: UpdateAgentByID :exec
|
||||
UPDATE agents
|
||||
SET agent_id=$1, agent_name=$2, architecture=$3, system=$4, hostname=$5, version=$6, capabilities=$7
|
||||
WHERE id=$8;
|
||||
@@ -0,0 +1,36 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
domainHub "github.com/lorsanstand/HomeOps-Hub/internal/hub/domain"
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/hub/store/sqlc/gen"
|
||||
)
|
||||
|
||||
type HubStore struct {
|
||||
queries *gen.Queries
|
||||
}
|
||||
|
||||
func NewHubStore(db *pgxpool.Pool) *HubStore {
|
||||
queries := gen.New(db)
|
||||
return &HubStore{queries}
|
||||
}
|
||||
|
||||
func (h *HubStore) NewAgent(ctx context.Context, agent domainHub.CreateAgentModel) error {
|
||||
return h.queries.CreateAgent(ctx, toDBAgent(agent))
|
||||
}
|
||||
|
||||
func (h *HubStore) GetAgentByAgentID(ctx context.Context, AgentID string) (domainHub.AgentModel, error) {
|
||||
data, err := h.queries.GetAgentByAgentID(ctx, AgentID)
|
||||
if err != nil {
|
||||
return domainHub.AgentModel{}, err
|
||||
}
|
||||
return toAgentModel(data), nil
|
||||
}
|
||||
|
||||
func (h *HubStore) UpdateAgentByID(ctx context.Context, ID int, updateAgent domainHub.CreateAgentModel) error {
|
||||
data := toUpdateDBAgent(updateAgent)
|
||||
data.ID = int32(ID)
|
||||
return h.queries.UpdateAgentByID(ctx, data)
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package hasher
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
||||
"github.com/lorsanstand/HomeOps-Hub/internal/domain"
|
||||
)
|
||||
|
||||
func newSalt(n int) ([]byte, error) {
|
||||
b := make([]byte, n)
|
||||
_, err := rand.Read(b)
|
||||
return b, err
|
||||
}
|
||||
|
||||
func MakeID(info domain.HostInfo, AgentName string) (string, error) {
|
||||
salt, err := newSalt(10)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
s := fmt.Sprintf("v1|host=%s|distro=%s|name=%s|", info.Hostname, info.Arch, AgentName)
|
||||
h := sha256.Sum256(append([]byte(s), salt...))
|
||||
return hex.EncodeToString(h[:16]), nil
|
||||
}
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
protoc \
|
||||
-I api/proto \
|
||||
--go_out=api/gen --go_opt=paths=source_relative \
|
||||
--go-grpc_out=api/gen --go-grpc_opt=paths=source_relative \
|
||||
api/proto/homeops/*.proto
|
||||
Reference in New Issue
Block a user