├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.yml
│ ├── config.yml
│ ├── docs_issue.yml
│ ├── feature_request.yml
│ └── request_help.yml
└── workflows
│ └── release.yaml
├── .gitignore
├── .gitlab-ci.yml
├── .golangci.yml
├── .goreleaser.yaml
├── README.md
├── app
├── .gitignore
├── apserver
│ ├── .gitignore
│ ├── apserver.go
│ ├── driver.go
│ ├── embed_plugin.go
│ ├── log.go
│ ├── main.go
│ ├── services.go
│ └── version
│ │ ├── dashboard.go
│ │ └── version.go
└── dynamic-module
│ ├── .gitignore
│ ├── file-access-log
│ ├── README.md
│ ├── plugin.yml
│ └── 文件日志.png
│ ├── http-access-log
│ ├── HTTP日志.png
│ ├── README.md
│ └── plugin.yml
│ ├── influxdb
│ ├── InfluxDB配置.png
│ ├── README.md
│ └── plugin.yml
│ ├── kafka-access-log
│ ├── Kafka日志.png
│ ├── README.md
│ └── plugin.yml
│ ├── nsqd-access-log
│ ├── NSQ日志.png
│ ├── README.md
│ └── plugin.yml
│ ├── package.sh
│ ├── redis
│ ├── README.md
│ ├── Redis配置.png
│ └── plugin.yml
│ └── syslog-access-log
│ ├── README.md
│ ├── SYSLOG日志.png
│ └── plugin.yml
├── cache
├── common-cache-mock
│ └── common-cache_mock.go
├── common.go
├── init.go
├── lock.go
├── locker.go
└── redis_cache.go
├── client
├── v1
│ ├── cert_api.go
│ ├── client.go
│ ├── client_test.go
│ ├── extender_api.go
│ ├── http_request.go
│ ├── initialize
│ │ └── plugin
│ │ │ ├── apinto_plugin.yml
│ │ │ ├── black_extended.go
│ │ │ ├── black_extended.yml
│ │ │ └── global.go
│ ├── model.go
│ ├── plugin_api.go
│ ├── profession.go
│ ├── proxy.go
│ ├── service.go
│ ├── strategy.go
│ └── variable_api.go
└── v2
│ ├── app.go
│ ├── client.go
│ ├── client_test.go
│ ├── cluster.go
│ ├── manager.go
│ ├── status.go
│ └── worker.go
├── common
├── aes.go
├── base64.go
├── cert.go
├── compress.go
├── const.go
├── diff.go
├── email.go
├── email_test.go
├── error.go
├── float64.go
├── gzip-static
│ ├── gzip.go
│ ├── gzip_test.go
│ ├── handler.go
│ └── options.go
├── http.go
├── interface_to_all.go
├── json.go
├── jwt.go
├── map.go
├── md5.go
├── panic.go
├── path.go
├── pool.go
├── rand.go
├── regexp.go
├── restful
│ ├── builder.go
│ ├── data.go
│ ├── path.go
│ ├── path_test.go
│ ├── request-call.go
│ ├── request-oneway.go
│ ├── request-rpc.go
│ ├── request-simple.go
│ ├── request.go
│ ├── restful.go
│ └── restful_test.go
├── schema
│ ├── README.md
│ ├── schema.go
│ └── schema_test.go
├── slice.go
├── slice_to_all.go
├── slices.go
├── time.go
├── webhook.go
├── webhook_test.go
└── yml.go
├── config
├── config.go
├── dir.go
├── redis.go
├── store-mysql.go
└── store.go
├── controller
├── .gitignore
├── audit.go
├── filters.go
├── gin_context.go
├── result.go
└── users
│ └── user.go
├── driver
└── driver_manager.go
├── enum
├── api_manager.go
├── change_opt_type.go
├── cluster_config.go
├── cluster_node_status.go
├── cluster_plugin.go
├── cluster_status.go
├── common.go
├── keyword.go
├── online_status_type.go
├── publish_opt.go
├── publish_type.go
└── variable_usage_status_type.go
├── filter
└── filter.go
├── frontend
├── .eslintrc.js
├── .gitignore
├── .npmrc
├── .prettierrc.json
├── .yarnrc
├── README.md
├── angular.json
├── frontend.go
├── jest.config.ts
├── package.json
├── projects
│ ├── core
│ │ └── src
│ │ │ ├── app
│ │ │ ├── app-routing.module.ts
│ │ │ ├── app.component.ts
│ │ │ ├── app.module.ts
│ │ │ ├── component
│ │ │ │ ├── api-method-tag
│ │ │ │ │ └── api-method-tag.component.ts
│ │ │ │ ├── card-list
│ │ │ │ │ └── card-list.component.ts
│ │ │ │ ├── component.module.ts
│ │ │ │ ├── copy-addr-list
│ │ │ │ │ └── copy-addr-list.component.ts
│ │ │ │ ├── dynamic-component
│ │ │ │ │ ├── dynamic-component.component.html
│ │ │ │ │ └── dynamic-component.component.ts
│ │ │ │ ├── editable-env-table
│ │ │ │ │ ├── editable-env-table.component.html
│ │ │ │ │ ├── editable-env-table.component.ts
│ │ │ │ │ └── editable-env-table.service.ts
│ │ │ │ ├── eo-ng-search-input-group
│ │ │ │ │ └── eo-ng-search-input-group.component.ts
│ │ │ │ ├── formily2-react
│ │ │ │ │ ├── CustomReactComponentWrapper.tsx
│ │ │ │ │ ├── IntelligentPluginEditComponent.tsx
│ │ │ │ │ ├── component
│ │ │ │ │ │ ├── array-item-blank
│ │ │ │ │ │ │ ├── ArrayItemBlankComponent.tsx
│ │ │ │ │ │ │ ├── ArrayItemBlankWrapperComponent.tsx
│ │ │ │ │ │ │ └── test-blank.json
│ │ │ │ │ │ ├── codebox
│ │ │ │ │ │ │ ├── CustomCodeboxComponent.tsx
│ │ │ │ │ │ │ └── CustomCodeboxComponentWrapper.tsx
│ │ │ │ │ │ ├── dialog
│ │ │ │ │ │ │ ├── CustomDialogComponent.tsx
│ │ │ │ │ │ │ └── CustomDialogComponentWrapper.tsx
│ │ │ │ │ │ ├── editable-env-table
│ │ │ │ │ │ │ ├── CustomEnvVariableComponent.tsx
│ │ │ │ │ │ │ ├── CustomEnvVariableComponentWrapper.tsx
│ │ │ │ │ │ │ └── CustomEnvVariableTableComponent.tsx
│ │ │ │ │ │ └── simple-map
│ │ │ │ │ │ │ ├── SimpleMapComponent.tsx
│ │ │ │ │ │ │ └── SimpleMapComponentWrapper.tsx
│ │ │ │ │ └── formily2-react.component.ts
│ │ │ │ ├── iframe
│ │ │ │ │ ├── iframe.component.html
│ │ │ │ │ └── iframe.component.ts
│ │ │ │ ├── intelligent-plugin
│ │ │ │ │ ├── create
│ │ │ │ │ │ ├── create.component.html
│ │ │ │ │ │ └── create.component.ts
│ │ │ │ │ ├── intelligent-plugin.service.ts
│ │ │ │ │ ├── layout
│ │ │ │ │ │ ├── layout.component.html
│ │ │ │ │ │ └── layout.component.ts
│ │ │ │ │ ├── list
│ │ │ │ │ │ ├── list.component.html
│ │ │ │ │ │ └── list.component.ts
│ │ │ │ │ ├── publish
│ │ │ │ │ │ ├── publish.component.html
│ │ │ │ │ │ └── publish.component.ts
│ │ │ │ │ └── types
│ │ │ │ │ │ ├── conf.ts
│ │ │ │ │ │ └── types.ts
│ │ │ │ ├── reset-psw
│ │ │ │ │ ├── reset-psw.component.html
│ │ │ │ │ └── reset-psw.component.ts
│ │ │ │ ├── table-status-td
│ │ │ │ │ └── table-status-td.component.ts
│ │ │ │ ├── user-avatar
│ │ │ │ │ ├── user-avatar.component.html
│ │ │ │ │ ├── user-avatar.component.scss
│ │ │ │ │ └── user-avatar.component.ts
│ │ │ │ └── user-profile
│ │ │ │ │ ├── user-profile.component.html
│ │ │ │ │ └── user-profile.component.ts
│ │ │ ├── constant
│ │ │ │ ├── app.config.ts
│ │ │ │ ├── conf.ts
│ │ │ │ ├── eo-ng-validator.ts
│ │ │ │ ├── form.ts
│ │ │ │ ├── spec-test.ts
│ │ │ │ └── type.ts
│ │ │ ├── custom-preloading-strategy.ts
│ │ │ ├── directive
│ │ │ │ ├── auto-focus.directive.ts
│ │ │ │ ├── directive.module.ts
│ │ │ │ ├── eo-ng-scroll-dom.directive.ts
│ │ │ │ ├── row-expand-button.directive.ts
│ │ │ │ ├── tree-drag.directive.ts
│ │ │ │ └── user-access.directive.ts
│ │ │ ├── layout
│ │ │ │ ├── api
│ │ │ │ │ ├── api-list
│ │ │ │ │ │ ├── api-list.component.ts
│ │ │ │ │ │ ├── create
│ │ │ │ │ │ │ ├── http-create
│ │ │ │ │ │ │ │ ├── http-create.component.spec.ts
│ │ │ │ │ │ │ │ └── http-create.component.ts
│ │ │ │ │ │ │ └── websocket-create
│ │ │ │ │ │ │ │ ├── websocket-create.component.html
│ │ │ │ │ │ │ │ ├── websocket-create.component.spec.ts
│ │ │ │ │ │ │ │ └── websocket-create.component.ts
│ │ │ │ │ │ ├── group
│ │ │ │ │ │ │ ├── edit-group
│ │ │ │ │ │ │ │ ├── edit-group.component.spec.ts
│ │ │ │ │ │ │ │ └── edit-group.component.ts
│ │ │ │ │ │ │ ├── group.component.html
│ │ │ │ │ │ │ ├── group.component.spec.ts
│ │ │ │ │ │ │ └── group.component.ts
│ │ │ │ │ │ ├── import
│ │ │ │ │ │ │ ├── import.component.html
│ │ │ │ │ │ │ ├── import.component.spec.ts
│ │ │ │ │ │ │ └── import.component.ts
│ │ │ │ │ │ ├── list
│ │ │ │ │ │ │ ├── list.component.html
│ │ │ │ │ │ │ ├── list.component.spec.ts
│ │ │ │ │ │ │ └── list.component.ts
│ │ │ │ │ │ ├── match
│ │ │ │ │ │ │ ├── form
│ │ │ │ │ │ │ │ ├── form.component.html
│ │ │ │ │ │ │ │ ├── form.component.spec.ts
│ │ │ │ │ │ │ │ └── form.component.ts
│ │ │ │ │ │ │ └── table
│ │ │ │ │ │ │ │ ├── table.component.html
│ │ │ │ │ │ │ │ ├── table.component.spec.ts
│ │ │ │ │ │ │ │ └── table.component.ts
│ │ │ │ │ │ ├── message
│ │ │ │ │ │ │ ├── http-message
│ │ │ │ │ │ │ │ └── http-message.component.ts
│ │ │ │ │ │ │ ├── message.component.spec.ts
│ │ │ │ │ │ │ ├── message.component.ts
│ │ │ │ │ │ │ └── websocket-message
│ │ │ │ │ │ │ │ └── websocket-message.component.ts
│ │ │ │ │ │ ├── proxy
│ │ │ │ │ │ │ ├── proxy.component.html
│ │ │ │ │ │ │ ├── proxy.component.spec.ts
│ │ │ │ │ │ │ └── proxy.component.ts
│ │ │ │ │ │ └── publish
│ │ │ │ │ │ │ ├── batch
│ │ │ │ │ │ │ ├── choose-cluster.component.html
│ │ │ │ │ │ │ ├── choose-cluster.component.ts
│ │ │ │ │ │ │ ├── result.component.html
│ │ │ │ │ │ │ └── result.component.ts
│ │ │ │ │ │ │ └── single
│ │ │ │ │ │ │ ├── publish.component.html
│ │ │ │ │ │ │ ├── publish.component.spec.ts
│ │ │ │ │ │ │ └── publish.component.ts
│ │ │ │ │ ├── api-routing.module.ts
│ │ │ │ │ ├── api.module.ts
│ │ │ │ │ ├── plugin
│ │ │ │ │ │ ├── config
│ │ │ │ │ │ │ ├── form
│ │ │ │ │ │ │ │ ├── form.component.html
│ │ │ │ │ │ │ │ └── form.component.ts
│ │ │ │ │ │ │ └── table
│ │ │ │ │ │ │ │ ├── table.component.html
│ │ │ │ │ │ │ │ └── table.component.ts
│ │ │ │ │ │ ├── content
│ │ │ │ │ │ │ └── content.component.ts
│ │ │ │ │ │ ├── create
│ │ │ │ │ │ │ ├── create.component.html
│ │ │ │ │ │ │ └── create.component.ts
│ │ │ │ │ │ ├── list
│ │ │ │ │ │ │ ├── list.component.html
│ │ │ │ │ │ │ └── list.component.ts
│ │ │ │ │ │ ├── message
│ │ │ │ │ │ │ └── message.component.ts
│ │ │ │ │ │ ├── plugin.component.ts
│ │ │ │ │ │ └── publish
│ │ │ │ │ │ │ ├── publish.component.html
│ │ │ │ │ │ │ └── publish.component.ts
│ │ │ │ │ ├── router.service.ts
│ │ │ │ │ ├── router
│ │ │ │ │ │ └── router.component.ts
│ │ │ │ │ └── types
│ │ │ │ │ │ ├── conf.ts
│ │ │ │ │ │ └── types.ts
│ │ │ │ ├── application
│ │ │ │ │ ├── application-routing.module.ts
│ │ │ │ │ ├── application.component.ts
│ │ │ │ │ ├── application.module.ts
│ │ │ │ │ ├── application.service.ts
│ │ │ │ │ ├── authentication
│ │ │ │ │ │ ├── authentication.component.html
│ │ │ │ │ │ ├── authentication.component.ts
│ │ │ │ │ │ ├── form
│ │ │ │ │ │ │ ├── form.component.html
│ │ │ │ │ │ │ └── form.component.ts
│ │ │ │ │ │ └── view
│ │ │ │ │ │ │ └── view.component.ts
│ │ │ │ │ ├── content
│ │ │ │ │ │ ├── content.component.html
│ │ │ │ │ │ └── content.component.ts
│ │ │ │ │ ├── create
│ │ │ │ │ │ ├── create.component.html
│ │ │ │ │ │ └── create.component.ts
│ │ │ │ │ ├── extra
│ │ │ │ │ │ ├── extra.component.html
│ │ │ │ │ │ ├── extra.component.ts
│ │ │ │ │ │ └── form
│ │ │ │ │ │ │ ├── form.component.html
│ │ │ │ │ │ │ └── form.component.ts
│ │ │ │ │ ├── list
│ │ │ │ │ │ └── list.component.ts
│ │ │ │ │ ├── message
│ │ │ │ │ │ ├── message.component.html
│ │ │ │ │ │ └── message.component.ts
│ │ │ │ │ ├── publish
│ │ │ │ │ │ └── publish.component.ts
│ │ │ │ │ └── types
│ │ │ │ │ │ ├── conf.ts
│ │ │ │ │ │ └── types.ts
│ │ │ │ ├── audit-log
│ │ │ │ │ ├── audit-log-routing.module.ts
│ │ │ │ │ ├── audit-log.component.ts
│ │ │ │ │ ├── audit-log.module.ts
│ │ │ │ │ ├── detail
│ │ │ │ │ │ └── detail.component.ts
│ │ │ │ │ ├── list
│ │ │ │ │ │ ├── list.component.html
│ │ │ │ │ │ └── list.component.ts
│ │ │ │ │ └── types
│ │ │ │ │ │ ├── conf.ts
│ │ │ │ │ │ └── types.ts
│ │ │ │ ├── auth
│ │ │ │ │ ├── activation
│ │ │ │ │ │ ├── activation.component.html
│ │ │ │ │ │ └── activation.component.ts
│ │ │ │ │ ├── info
│ │ │ │ │ │ ├── detail
│ │ │ │ │ │ │ └── detail.component.ts
│ │ │ │ │ │ ├── info.component.html
│ │ │ │ │ │ └── info.component.ts
│ │ │ │ │ └── update
│ │ │ │ │ │ └── update.component.ts
│ │ │ │ ├── basic-layout
│ │ │ │ │ ├── basic-layout.component.html
│ │ │ │ │ ├── basic-layout.component.scss
│ │ │ │ │ └── basic-layout.component.ts
│ │ │ │ ├── deploy
│ │ │ │ │ ├── cluster
│ │ │ │ │ │ ├── cert
│ │ │ │ │ │ │ ├── cert.component.html
│ │ │ │ │ │ │ ├── cert.component.ts
│ │ │ │ │ │ │ └── form
│ │ │ │ │ │ │ │ ├── form.component.html
│ │ │ │ │ │ │ │ └── form.component.ts
│ │ │ │ │ │ ├── cluster.component.html
│ │ │ │ │ │ ├── cluster.component.ts
│ │ │ │ │ │ ├── content
│ │ │ │ │ │ │ ├── content.component.html
│ │ │ │ │ │ │ └── content.component.ts
│ │ │ │ │ │ ├── create
│ │ │ │ │ │ │ ├── create.component.html
│ │ │ │ │ │ │ └── create.component.ts
│ │ │ │ │ │ ├── environment
│ │ │ │ │ │ │ ├── config
│ │ │ │ │ │ │ │ ├── form
│ │ │ │ │ │ │ │ │ └── form.component.ts
│ │ │ │ │ │ │ │ └── update
│ │ │ │ │ │ │ │ │ └── update.component.ts
│ │ │ │ │ │ │ ├── environment.component.html
│ │ │ │ │ │ │ ├── environment.component.ts
│ │ │ │ │ │ │ ├── history
│ │ │ │ │ │ │ │ ├── change
│ │ │ │ │ │ │ │ │ └── change.component.ts
│ │ │ │ │ │ │ │ └── publish
│ │ │ │ │ │ │ │ │ └── publish.component.ts
│ │ │ │ │ │ │ └── publish
│ │ │ │ │ │ │ │ └── publish.component.ts
│ │ │ │ │ │ ├── list
│ │ │ │ │ │ │ ├── list.component.html
│ │ │ │ │ │ │ └── list.component.ts
│ │ │ │ │ │ ├── message
│ │ │ │ │ │ │ ├── message.component.html
│ │ │ │ │ │ │ └── message.component.ts
│ │ │ │ │ │ ├── nodes
│ │ │ │ │ │ │ ├── form
│ │ │ │ │ │ │ │ └── form.component.ts
│ │ │ │ │ │ │ ├── nodes.component.html
│ │ │ │ │ │ │ └── nodes.component.ts
│ │ │ │ │ │ ├── plugin
│ │ │ │ │ │ │ ├── config
│ │ │ │ │ │ │ │ ├── config.component.html
│ │ │ │ │ │ │ │ └── config.component.ts
│ │ │ │ │ │ │ ├── history
│ │ │ │ │ │ │ │ ├── change
│ │ │ │ │ │ │ │ │ ├── change.component.html
│ │ │ │ │ │ │ │ │ └── change.component.ts
│ │ │ │ │ │ │ │ └── publish
│ │ │ │ │ │ │ │ │ ├── publish.component.html
│ │ │ │ │ │ │ │ │ └── publish.component.ts
│ │ │ │ │ │ │ ├── plugin.component.html
│ │ │ │ │ │ │ ├── plugin.component.ts
│ │ │ │ │ │ │ └── publish
│ │ │ │ │ │ │ │ └── publish.component.ts
│ │ │ │ │ │ └── types
│ │ │ │ │ │ │ ├── conf.ts
│ │ │ │ │ │ │ └── types.ts
│ │ │ │ │ ├── deploy-routing.module.ts
│ │ │ │ │ ├── deploy.module.ts
│ │ │ │ │ ├── deploy.service.ts
│ │ │ │ │ ├── environment
│ │ │ │ │ │ ├── create
│ │ │ │ │ │ │ ├── create.component.html
│ │ │ │ │ │ │ └── create.component.ts
│ │ │ │ │ │ ├── detail
│ │ │ │ │ │ │ └── detail.component.ts
│ │ │ │ │ │ ├── environment.component.ts
│ │ │ │ │ │ ├── list
│ │ │ │ │ │ │ ├── list.component.html
│ │ │ │ │ │ │ └── list.component.ts
│ │ │ │ │ │ └── types
│ │ │ │ │ │ │ ├── conf.ts
│ │ │ │ │ │ │ └── types.ts
│ │ │ │ │ └── plugin
│ │ │ │ │ │ ├── create
│ │ │ │ │ │ ├── create.component.html
│ │ │ │ │ │ └── create.component.ts
│ │ │ │ │ │ ├── deploy-plugin.component.ts
│ │ │ │ │ │ ├── list
│ │ │ │ │ │ ├── list.component.html
│ │ │ │ │ │ └── list.component.ts
│ │ │ │ │ │ ├── message
│ │ │ │ │ │ └── message.component.ts
│ │ │ │ │ │ └── types
│ │ │ │ │ │ ├── conf.ts
│ │ │ │ │ │ └── types.ts
│ │ │ │ ├── dynamic-demo
│ │ │ │ │ └── dynamic-demo.component.ts
│ │ │ │ ├── guide
│ │ │ │ │ ├── conf.ts
│ │ │ │ │ ├── guide.component.html
│ │ │ │ │ └── guide.component.ts
│ │ │ │ ├── intelligent-plugin
│ │ │ │ │ ├── create
│ │ │ │ │ │ └── create.component.ts
│ │ │ │ │ ├── intelligent-plugin-routing.module.ts
│ │ │ │ │ ├── intelligent-plugin.component.ts
│ │ │ │ │ ├── intelligent-plugin.module.ts
│ │ │ │ │ ├── layout
│ │ │ │ │ │ └── layout.component.ts
│ │ │ │ │ ├── list
│ │ │ │ │ │ └── list.component.ts
│ │ │ │ │ └── publish
│ │ │ │ │ │ └── publish.component.ts
│ │ │ │ ├── layout.module.ts
│ │ │ │ ├── local-plugin
│ │ │ │ │ └── local-plugin.component.ts
│ │ │ │ ├── log-retrieval
│ │ │ │ │ ├── conf.ts
│ │ │ │ │ ├── log-retrieval-routing.module.ts
│ │ │ │ │ ├── log-retrieval.component.html
│ │ │ │ │ ├── log-retrieval.component.ts
│ │ │ │ │ ├── log-retrieval.module.ts
│ │ │ │ │ ├── tail-log
│ │ │ │ │ │ └── tail-log.component.ts
│ │ │ │ │ └── type.ts
│ │ │ │ ├── login
│ │ │ │ │ ├── login.component.html
│ │ │ │ │ ├── login.component.scss
│ │ │ │ │ ├── login.component.ts
│ │ │ │ │ ├── logo
│ │ │ │ │ │ ├── logo.component.html
│ │ │ │ │ │ ├── logo.component.scss
│ │ │ │ │ │ └── logo.component.ts
│ │ │ │ │ └── password
│ │ │ │ │ │ ├── password.component.html
│ │ │ │ │ │ ├── password.component.scss
│ │ │ │ │ │ └── password.component.ts
│ │ │ │ ├── not-found-page
│ │ │ │ │ └── not-found-page.component.ts
│ │ │ │ ├── plugin
│ │ │ │ │ ├── config
│ │ │ │ │ │ ├── config.component.html
│ │ │ │ │ │ └── config.component.ts
│ │ │ │ │ ├── create
│ │ │ │ │ │ └── create.component.ts
│ │ │ │ │ ├── eo-ng-plugin.service.ts
│ │ │ │ │ ├── group
│ │ │ │ │ │ ├── group.component.html
│ │ │ │ │ │ └── group.component.ts
│ │ │ │ │ ├── list
│ │ │ │ │ │ ├── list.component.html
│ │ │ │ │ │ └── list.component.ts
│ │ │ │ │ ├── message
│ │ │ │ │ │ ├── message.component.scss
│ │ │ │ │ │ └── message.component.ts
│ │ │ │ │ ├── plugin-management-routing.module.ts
│ │ │ │ │ ├── plugin-management.component.ts
│ │ │ │ │ ├── plugin-management.module.ts
│ │ │ │ │ └── types
│ │ │ │ │ │ ├── conf.ts
│ │ │ │ │ │ └── types.ts
│ │ │ │ ├── remote-plugin
│ │ │ │ │ └── remote-plugin.component.ts
│ │ │ │ ├── serv-governance
│ │ │ │ │ ├── cache
│ │ │ │ │ │ ├── cache.component.ts
│ │ │ │ │ │ ├── create
│ │ │ │ │ │ │ ├── create.component.html
│ │ │ │ │ │ │ └── create.component.ts
│ │ │ │ │ │ └── message
│ │ │ │ │ │ │ └── message.component.ts
│ │ │ │ │ ├── filter
│ │ │ │ │ │ ├── footer
│ │ │ │ │ │ │ ├── footer.component.html
│ │ │ │ │ │ │ └── footer.component.ts
│ │ │ │ │ │ ├── form
│ │ │ │ │ │ │ ├── form.component.html
│ │ │ │ │ │ │ └── form.component.ts
│ │ │ │ │ │ ├── serv-governance-filter.service.ts
│ │ │ │ │ │ └── table
│ │ │ │ │ │ │ ├── table.component.html
│ │ │ │ │ │ │ └── table.component.ts
│ │ │ │ │ ├── fuse
│ │ │ │ │ │ ├── create
│ │ │ │ │ │ │ ├── create.component.html
│ │ │ │ │ │ │ └── create.component.ts
│ │ │ │ │ │ ├── fuse.component.ts
│ │ │ │ │ │ └── message
│ │ │ │ │ │ │ └── message.component.ts
│ │ │ │ │ ├── grey
│ │ │ │ │ │ ├── create
│ │ │ │ │ │ │ ├── create.component.html
│ │ │ │ │ │ │ └── create.component.ts
│ │ │ │ │ │ ├── grey.component.ts
│ │ │ │ │ │ └── message
│ │ │ │ │ │ │ └── message.component.ts
│ │ │ │ │ ├── group
│ │ │ │ │ │ ├── group.component.html
│ │ │ │ │ │ └── group.component.ts
│ │ │ │ │ ├── list
│ │ │ │ │ │ ├── list.component.html
│ │ │ │ │ │ └── list.component.ts
│ │ │ │ │ ├── publish
│ │ │ │ │ │ └── publish.component.ts
│ │ │ │ │ ├── response-form
│ │ │ │ │ │ ├── response-form.component.html
│ │ │ │ │ │ └── response-form.component.ts
│ │ │ │ │ ├── serv-governance-routing.module.ts
│ │ │ │ │ ├── serv-governance.module.ts
│ │ │ │ │ ├── service-governance.component.ts
│ │ │ │ │ ├── service-governance.service.ts
│ │ │ │ │ ├── traffic
│ │ │ │ │ │ ├── create
│ │ │ │ │ │ │ ├── create.component.html
│ │ │ │ │ │ │ └── create.component.ts
│ │ │ │ │ │ ├── message
│ │ │ │ │ │ │ ├── message.component.html
│ │ │ │ │ │ │ └── message.component.ts
│ │ │ │ │ │ └── traffic.component.ts
│ │ │ │ │ ├── types
│ │ │ │ │ │ ├── conf.ts
│ │ │ │ │ │ └── types.ts
│ │ │ │ │ └── visit
│ │ │ │ │ │ ├── create
│ │ │ │ │ │ ├── create.component.html
│ │ │ │ │ │ └── create.component.ts
│ │ │ │ │ │ ├── message
│ │ │ │ │ │ └── message.component.ts
│ │ │ │ │ │ └── visit.component.ts
│ │ │ │ └── system
│ │ │ │ │ ├── email
│ │ │ │ │ ├── config
│ │ │ │ │ │ ├── config.component.html
│ │ │ │ │ │ └── config.component.ts
│ │ │ │ │ └── system-email.component.ts
│ │ │ │ │ ├── external-app
│ │ │ │ │ ├── create
│ │ │ │ │ │ ├── create.component.html
│ │ │ │ │ │ └── create.component.ts
│ │ │ │ │ ├── external-app.component.ts
│ │ │ │ │ ├── list
│ │ │ │ │ │ ├── list.component.html
│ │ │ │ │ │ └── list.component.ts
│ │ │ │ │ └── message
│ │ │ │ │ │ └── message.component.ts
│ │ │ │ │ ├── system-routing.module.ts
│ │ │ │ │ ├── system.component.ts
│ │ │ │ │ ├── system.module.ts
│ │ │ │ │ ├── types
│ │ │ │ │ ├── conf.ts
│ │ │ │ │ └── type.ts
│ │ │ │ │ └── webhook
│ │ │ │ │ ├── config
│ │ │ │ │ ├── config.component.html
│ │ │ │ │ └── config.component.ts
│ │ │ │ │ ├── list
│ │ │ │ │ ├── list.component.html
│ │ │ │ │ └── list.component.ts
│ │ │ │ │ └── webhook.component.ts
│ │ │ ├── pipe
│ │ │ │ ├── change-word-color.pipe.ts
│ │ │ │ └── safe.pipe.ts
│ │ │ └── service
│ │ │ │ ├── api.service.ts
│ │ │ │ ├── auth-guard.service.ts
│ │ │ │ ├── base-info.service.ts
│ │ │ │ ├── crypto.service.ts
│ │ │ │ ├── eo-ng-json.service.ts
│ │ │ │ ├── eo-ng-message.service.ts
│ │ │ │ ├── eo-ng-navigation.service.ts
│ │ │ │ ├── http-interceptors
│ │ │ │ ├── error.interceptor.ts
│ │ │ │ └── index.ts
│ │ │ │ ├── iframe-http.service.ts
│ │ │ │ ├── publish-fail.service.ts
│ │ │ │ ├── redirect-page.service.ts
│ │ │ │ └── websocket.service.ts
│ │ │ ├── assets
│ │ │ ├── .gitkeep
│ │ │ ├── README.md
│ │ │ ├── apinto-auth.svg
│ │ │ ├── apinto-pro.svg
│ │ │ ├── apinto.svg
│ │ │ ├── avatar.svg
│ │ │ ├── default-guide-icon.png
│ │ │ ├── default-navigation-icon.png
│ │ │ ├── default-plugin-icon.svg
│ │ │ ├── favicon-pro.ico
│ │ │ ├── favicon.ico
│ │ │ ├── guide.jpg
│ │ │ ├── iconpark-apinto.js
│ │ │ ├── iconpark.js
│ │ │ ├── logo
│ │ │ │ ├── logo_dark.png
│ │ │ │ └── logo_light.png
│ │ │ ├── no-access.svg
│ │ │ ├── side_bg.jpg
│ │ │ └── theme
│ │ │ │ ├── dark.json
│ │ │ │ └── light.json
│ │ │ ├── environments
│ │ │ ├── basic.ts
│ │ │ ├── environment.business.prod.ts
│ │ │ ├── environment.business.ts
│ │ │ ├── environment.prod.ts
│ │ │ └── environment.ts
│ │ │ ├── favicon.ico
│ │ │ ├── form.style.scss
│ │ │ ├── formily.style.scss
│ │ │ ├── index.html
│ │ │ ├── input.style.scss
│ │ │ ├── layout.style.scss
│ │ │ ├── main.ts
│ │ │ ├── polyfills.ts
│ │ │ ├── select.style.scss
│ │ │ ├── styles.scss
│ │ │ ├── table.style.scss
│ │ │ └── variables.css
│ └── eo-ng-apinto-table
│ │ ├── README.md
│ │ ├── ng-package.json
│ │ ├── package.json
│ │ ├── src
│ │ ├── lib
│ │ │ ├── eo-ng-apinto-table.module.ts
│ │ │ ├── table
│ │ │ │ ├── table.component.html
│ │ │ │ └── table.component.ts
│ │ │ └── types.ts
│ │ └── public-api.ts
│ │ ├── tsconfig.json
│ │ ├── tsconfig.lib.json
│ │ ├── tsconfig.lib.prod.json
│ │ └── tsconfig.spec.json
├── proxy.config.demo.json
├── tailwind.config.js
├── test
│ └── setup-jest.ts
├── tool
│ └── replaceCssVariable.js
├── tsconfig.app.json
├── tsconfig.json
└── tsconfig.spec.json
├── go.mod
├── go.sum
├── grpc-service
├── infos.pb.go
├── infos.proto
├── notice_send.pb.go
└── notice_send.proto
├── initialize
├── inner-plugin-manager
│ ├── embed_plugin.go
│ ├── export.go
│ ├── interface.go
│ └── manager.go
├── navigation.go
├── navigation.yml
├── navigation
│ ├── navigation.go
│ └── navigation.yml
├── plugin-group
│ ├── plugin_group.go
│ └── plugin_group.yml
├── plugin_group.go
├── plugin_group.yml
├── plugins.g.go
└── plugins
│ ├── embed
│ ├── api.apinto.com
│ │ ├── README.md
│ │ ├── logo.png
│ │ └── plugin.yml
│ ├── apispace.apinto.com
│ │ ├── README.md
│ │ ├── apispace.jpg
│ │ └── plugin.yml
│ ├── application.apinto.com
│ │ ├── README.md
│ │ ├── logo.png
│ │ └── plugin.yml
│ ├── audit.apinto.com
│ │ ├── README.md
│ │ ├── logo.png
│ │ └── plugin.yml
│ ├── cluster.apinto.com
│ │ ├── README.md
│ │ ├── logo.png
│ │ └── plugin.yml
│ ├── discovery.apinto.com
│ │ ├── README.md
│ │ ├── logo.png
│ │ └── plugin.yml
│ ├── email.apinto.com
│ │ ├── README.md
│ │ ├── logo.png
│ │ └── plugin.yml
│ ├── ext_app.apinto.com
│ │ ├── README.md
│ │ ├── logo.png
│ │ └── plugin.yml
│ ├── log.apinto.com
│ │ ├── README.md
│ │ ├── plugin.yml
│ │ └── 日志检索.png
│ ├── module_plugin.apinto.com
│ │ ├── README.md
│ │ ├── logo.png
│ │ └── plugin.yml
│ ├── open_api.apinto.com
│ │ ├── README.md
│ │ ├── logo.png
│ │ └── plugin.yml
│ ├── plugin.apinto.com
│ │ ├── README.md
│ │ ├── logo.png
│ │ └── plugin.yml
│ ├── plugin_template.apinto.com
│ │ ├── README.md
│ │ ├── logo.png
│ │ └── plugin.yml
│ ├── strategy-cache.apinto.com
│ │ ├── README.md
│ │ ├── logo.png
│ │ └── plugin.yml
│ ├── strategy-fuse.apinto.com
│ │ ├── README.md
│ │ ├── logo.png
│ │ └── plugin.yml
│ ├── strategy-grey.apinto.com
│ │ ├── README.md
│ │ ├── logo.png
│ │ └── plugin.yml
│ ├── strategy-traffic.apinto.com
│ │ ├── README.md
│ │ ├── logo.png
│ │ └── plugin.yml
│ ├── strategy-visit.apinto.com
│ │ ├── README.md
│ │ ├── logo.png
│ │ └── plugin.yml
│ ├── upstream.apinto.com
│ │ ├── README.md
│ │ ├── logo.png
│ │ └── plugin.yml
│ ├── variable.apinto.com
│ │ ├── README.md
│ │ ├── logo.png
│ │ └── plugin.yml
│ └── webhook.apinto.com
│ │ ├── README.md
│ │ ├── logo.png
│ │ └── plugin.yml
│ └── plugins.g.go
├── module
├── access-reader.go
├── builder.go
├── builder_test.go
├── driver.go
├── handler.go
├── middleware-request.go
├── middleware-response.go
├── middleware.go
├── module.go
├── options.go
├── plugin.go
├── provider.go
├── repeat-read.go
├── response-update.go
├── response-update_test.go
└── simple.go
├── modules
├── api
│ ├── api-dto
│ │ └── api.go
│ ├── api-entry
│ │ ├── api.go
│ │ ├── api_history.go
│ │ ├── api_runtime.go
│ │ ├── api_stat.go
│ │ ├── api_version.go
│ │ └── publish_history.go
│ ├── api.go
│ ├── controller
│ │ ├── api.go
│ │ ├── module.go
│ │ ├── options.go
│ │ └── routers.go
│ ├── driver
│ │ ├── api_http.go
│ │ ├── api_websocket.go
│ │ └── common.go
│ ├── mock
│ │ └── api_mock.go
│ ├── model
│ │ └── api.go
│ ├── service
│ │ ├── api-driver.go
│ │ ├── api.go
│ │ ├── batch_online_api.go
│ │ ├── import_api_data.go
│ │ └── init.go
│ ├── status-code
│ │ └── code.go
│ └── store
│ │ ├── api.go
│ │ ├── api_history.go
│ │ ├── api_stat.go
│ │ ├── api_version.go
│ │ ├── init.go
│ │ └── publish_history.go
├── application
│ ├── application-controller
│ │ ├── application.go
│ │ ├── module.go
│ │ ├── options.go
│ │ └── routers.go
│ ├── application-dto
│ │ ├── application.go
│ │ └── application_auth.go
│ ├── application-entry
│ │ ├── application.go
│ │ ├── application_auth.go
│ │ └── application_auth_publish.go
│ ├── application-model
│ │ ├── application.go
│ │ └── application_auth.go
│ ├── application-service
│ │ ├── application.go
│ │ ├── auth.go
│ │ ├── driver.go
│ │ └── init.go
│ ├── application-store
│ │ ├── application.go
│ │ ├── application_auth.go
│ │ ├── application_history.go
│ │ ├── application_stat.go
│ │ ├── application_version.go
│ │ ├── init.go
│ │ └── publish_history.go
│ ├── application_service.go
│ └── driver
│ │ ├── aksk.go
│ │ ├── apikey.go
│ │ ├── basic.go
│ │ ├── common.go
│ │ └── jwt.go
├── audit
│ ├── audit-controller
│ │ ├── audit.go
│ │ ├── audit_log.go
│ │ └── module.go
│ ├── audit-entry
│ │ └── audit_log.go
│ ├── audit-model
│ │ ├── audit_log.go
│ │ └── operater.go
│ ├── audit-service
│ │ ├── audit_log.go
│ │ └── init.go
│ ├── audit-store
│ │ ├── audit_log.go
│ │ └── init.go
│ └── audit.go
├── base
│ ├── env-controller
│ │ └── enum.go
│ ├── env-model
│ │ └── cluster_enum.go
│ ├── frontend-model
│ │ └── frontend.go
│ ├── history-entry
│ │ └── history.go
│ ├── locker-service
│ │ ├── init.go
│ │ └── lock.go
│ ├── namespace-controller
│ │ └── namespace.go
│ ├── publish-entry
│ │ └── publish_history.go
│ ├── quote-entry
│ │ └── quote.go
│ ├── quote-store
│ │ ├── init.go
│ │ └── quote.go
│ ├── random-controller
│ │ └── random.go
│ ├── runtime-entry
│ │ └── runtime.go
│ ├── stat-entry
│ │ └── stat.go
│ └── version-entry
│ │ └── version.go
├── cluster
│ ├── cluster-controller
│ │ ├── cluster.go
│ │ ├── cluster_certificate.go
│ │ ├── cluster_node.go
│ │ └── module.go
│ ├── cluster-dto
│ │ ├── cluster.go
│ │ ├── cluster_certificate.go
│ │ ├── cluster_config.go
│ │ ├── cluster_node.go
│ │ └── cluster_variable.go
│ ├── cluster-entry
│ │ ├── cluster.go
│ │ ├── cluster_certificate.go
│ │ ├── cluster_config_runtime.go
│ │ └── cluster_node.go
│ ├── cluster-mock
│ │ └── cluster_mock.go
│ ├── cluster-model
│ │ ├── cluster.go
│ │ ├── cluster_certificate.go
│ │ └── cluster_node.go
│ ├── cluster-service
│ │ ├── apinto_client.go
│ │ ├── cluster.go
│ │ ├── cluster_certificate.go
│ │ ├── cluster_node.go
│ │ ├── init.go
│ │ └── node_cache.go
│ ├── cluster-store
│ │ ├── cluster.go
│ │ ├── cluster_certificate.go
│ │ ├── cluster_history.go
│ │ ├── cluster_node.go
│ │ ├── cluster_runtime.go
│ │ └── init.go
│ └── service.go
├── core
│ ├── controller
│ │ ├── common-strategy.go
│ │ ├── env.go
│ │ ├── expire.go
│ │ ├── frontend.go
│ │ ├── module-controller.go
│ │ ├── module.go
│ │ ├── report.go
│ │ ├── session.go
│ │ ├── system.go
│ │ └── user.go
│ ├── model
│ │ └── navigation.go
│ ├── service.go
│ └── service
│ │ ├── init.go
│ │ ├── navigation.go
│ │ ├── provider.go
│ │ └── service.go
├── dynamic
│ ├── dynamic-controller
│ │ ├── define.go
│ │ ├── dynamic.go
│ │ ├── module.go
│ │ ├── options.go
│ │ └── provider.go
│ ├── dynamic-dto
│ │ ├── cluster.go
│ │ └── dynamic.go
│ ├── dynamic-entry
│ │ ├── dynamic.go
│ │ ├── dynamic_publish_history.go
│ │ ├── dynamic_publish_version.go
│ │ ├── dynamic_quote.go
│ │ └── sql.sql
│ ├── dynamic-model
│ │ ├── dynamic.go
│ │ └── render.go
│ ├── dynamic-service
│ │ ├── dynamic.go
│ │ ├── init.go
│ │ └── variable.go
│ ├── dynamic-store
│ │ ├── dynamic.go
│ │ ├── dynamic_publish_history.go
│ │ ├── dynamic_publish_version.go
│ │ ├── dynamic_quote.go
│ │ └── init.go
│ └── dynamic.go
├── email
│ ├── controller
│ │ ├── email.go
│ │ └── module.go
│ └── dto
│ │ └── email.go
├── group
│ ├── group-controller
│ │ └── common_group.go
│ ├── group-dto
│ │ └── common_group.go
│ ├── group-entry
│ │ └── common_group.go
│ ├── group-model
│ │ └── common_group.go
│ ├── group-service
│ │ ├── common_group.go
│ │ └── init.go
│ ├── group-store
│ │ ├── common_group.go
│ │ └── init.go
│ └── group.go
├── grpc-service
│ └── service
│ │ ├── cache.go
│ │ ├── console_info.go
│ │ ├── error.go
│ │ ├── init.go
│ │ └── notice_send.go
├── log
│ ├── dto
│ │ ├── arg.go
│ │ └── output.go
│ └── module
│ │ ├── client.go
│ │ ├── conn.go
│ │ ├── controller.go
│ │ ├── download.go
│ │ ├── driver.go
│ │ ├── module.go
│ │ ├── tail.go
│ │ └── util.go
├── module-plugin
│ ├── controller
│ │ ├── module.go
│ │ ├── module_plugin.go
│ │ └── plugin_front.go
│ ├── dto
│ │ └── module_plugin.go
│ ├── embed_registry
│ │ └── embed_plugin.go
│ ├── entry
│ │ ├── module_plugin.go
│ │ ├── module_plugin_enable.go
│ │ ├── module_plugin_package.go
│ │ └── module_plugin_resources.go
│ ├── model
│ │ ├── module_plugin.go
│ │ ├── plugin_front.go
│ │ └── plugin_resources.go
│ ├── module_plugin.go
│ ├── resources_manager
│ │ └── manager.go
│ ├── service
│ │ ├── common.go
│ │ ├── enum.go
│ │ ├── error.go
│ │ ├── init.go
│ │ ├── installed_cache.go
│ │ ├── module_plugin.go
│ │ ├── module_plugin_service.go
│ │ └── navigation_modules_cache.go
│ └── store
│ │ ├── init.go
│ │ ├── module_plugin.go
│ │ ├── module_plugin_enable.go
│ │ ├── module_plugin_package.go
│ │ └── module_plugin_resources.go
├── namespace
│ ├── namespace-entry
│ │ └── namespace.go
│ ├── namespace-mock
│ │ └── namespace_mock.go
│ ├── namespace-model
│ │ └── namespace.go
│ ├── namespace-service
│ │ ├── init.go
│ │ └── namespace.go
│ ├── namespace-store
│ │ ├── init.go
│ │ └── namespace.go
│ └── service.go
├── navigation
│ ├── navigation-model
│ │ └── navigation.go
│ ├── navigation-service
│ │ ├── init.go
│ │ └── navigation.go
│ └── navigation.go
├── notice
│ ├── controller
│ │ ├── notice.go
│ │ └── routers.go
│ ├── driver.go
│ ├── dto
│ │ └── notice.go
│ ├── notice-entry
│ │ └── notice_channel.go
│ ├── notice-mock
│ │ └── notice_mock.go
│ ├── notice-model
│ │ └── notice_channel.go
│ ├── notice-service
│ │ ├── driver.go
│ │ ├── init.go
│ │ └── notice_channel.go
│ ├── notice-store
│ │ ├── init.go
│ │ ├── notice_channel.go
│ │ ├── notice_channel_stat.go
│ │ └── notice_channel_version.go
│ └── notice.go
├── online
│ ├── online-dto
│ │ └── common_online.go
│ └── service.go
├── openapi
│ ├── driver
│ │ ├── openAPI3.go
│ │ └── swagger2.go
│ ├── open-api-controller
│ │ ├── api_openAPI.go
│ │ ├── module.go
│ │ └── routers.go
│ ├── openapi-dto
│ │ └── api_openAPI.go
│ ├── openapi-model
│ │ └── api_openAPI.go
│ ├── openapi-service
│ │ ├── api_openAPI.go
│ │ └── init.go
│ └── openapi.go
├── openapp
│ ├── open-app-controller
│ │ ├── external_app.go
│ │ ├── module.go
│ │ └── routers.go
│ ├── open-app-dto
│ │ └── external_app.go
│ ├── open-app-entry
│ │ └── external_app.go
│ ├── open-app-model
│ │ ├── external-app.go
│ │ └── swagger.go
│ ├── openapp-service
│ │ ├── api_import_format.go
│ │ ├── external-app.go
│ │ └── init.go
│ ├── openapp-store
│ │ ├── external_app.go
│ │ └── init.go
│ └── openapp.go
├── plugin
│ ├── cluster_plugin_service.go
│ ├── plugin-controller
│ │ ├── cluster_plugin.go
│ │ ├── module.go
│ │ └── plugin.go
│ ├── plugin-dto
│ │ ├── cluster_plugin.go
│ │ └── plugin.go
│ ├── plugin-entry
│ │ ├── cluster_plugin.go
│ │ ├── cluster_plugin_history.go
│ │ ├── cluster_plugin_publish_history.go
│ │ ├── cluster_plugin_publish_version.go
│ │ ├── cluster_plugin_runtime.go
│ │ ├── plugin.go
│ │ └── plugin_history.go
│ ├── plugin-model
│ │ ├── cluster_plugin.go
│ │ └── plugin.go
│ ├── plugin-service
│ │ ├── cluster_plugin.go
│ │ ├── extender_cache.go
│ │ ├── init.go
│ │ └── plugin.go
│ ├── plugin-store
│ │ ├── cluster_plugin.go
│ │ ├── cluster_plugin_history.go
│ │ ├── cluster_plugin_publish_history.go
│ │ ├── cluster_plugin_publish_version.go
│ │ ├── cluster_plugin_runtime.go
│ │ ├── init.go
│ │ ├── plugin.go
│ │ └── plugin_history.go
│ ├── plugin_service.go
│ └── plugin_timer
│ │ ├── extender.go
│ │ └── init.go
├── plugin_template
│ ├── plugin-template-controller
│ │ ├── module.go
│ │ └── plugin_template.go
│ ├── plugin-template-dto
│ │ └── plugin_template.go
│ ├── plugin-template-entry
│ │ ├── plugin_template.go
│ │ ├── plugin_template_history.go
│ │ ├── plugin_template_runtime.go
│ │ ├── plugin_template_stat.go
│ │ ├── plugin_template_version.go
│ │ └── publish_history.go
│ ├── plugin-template-model
│ │ └── plugin_template.go
│ ├── plugin-template-service
│ │ ├── init.go
│ │ └── plugin_template.go
│ ├── plugin-template-store
│ │ ├── init.go
│ │ ├── plugin_template.go
│ │ ├── plugin_template_history.go
│ │ ├── plugin_template_runtime.go
│ │ ├── plugin_template_stat.go
│ │ ├── plugin_template_version.go
│ │ └── publish_history.go
│ └── plugin_template_service.go
├── random
│ ├── random-service
│ │ ├── init.go
│ │ └── random.go
│ └── random.go
├── remote_storage
│ ├── entry
│ │ └── remote_key_object.go
│ ├── model
│ │ └── remote_storage.go
│ ├── remote_storage.go
│ ├── service
│ │ ├── init.go
│ │ └── remote_storage.go
│ └── store
│ │ ├── init.go
│ │ └── remote_storage.go
├── strategy
│ ├── config
│ │ ├── content-type.go
│ │ ├── content-type.yml
│ │ ├── metrics.go
│ │ ├── strategy.go
│ │ └── strategy_status.go
│ ├── strategy-controller
│ │ ├── module-cache.go
│ │ ├── module-fuse.go
│ │ ├── module-grey.go
│ │ ├── module-traffic.go
│ │ ├── module-visit.go
│ │ ├── stragety-traffic.go
│ │ ├── strategy-cache.go
│ │ ├── strategy-common.go
│ │ ├── strategy-fuse.go
│ │ ├── strategy-grey.go
│ │ ├── strategy-visit.go
│ │ └── strategy.go
│ ├── strategy-dto
│ │ └── strategy.go
│ ├── strategy-entry
│ │ ├── strategy.go
│ │ ├── strategy_history.go
│ │ ├── strategy_publish_history.go
│ │ ├── strategy_publish_version.go
│ │ ├── strategy_runtime.go
│ │ ├── strategy_stat.go
│ │ └── strategy_version.go
│ ├── strategy-model
│ │ └── strategy.go
│ ├── strategy-service
│ │ ├── filters.go
│ │ ├── init.go
│ │ ├── strategy-common.go
│ │ ├── strategy-handler
│ │ │ ├── cache.go
│ │ │ ├── check.go
│ │ │ ├── fuse.go
│ │ │ ├── grey.go
│ │ │ ├── traffic.go
│ │ │ └── visit.go
│ │ └── strategy.go
│ ├── strategy-store
│ │ ├── init.go
│ │ ├── strategy.go
│ │ ├── strategy_history.go
│ │ ├── strategy_publish_history.go
│ │ ├── strategy_publish_version.go
│ │ ├── strategy_runtime.go
│ │ ├── strategy_stat.go
│ │ └── strategy_version.go
│ └── strategy.go
├── system
│ ├── service
│ │ ├── data-key.go
│ │ ├── data.go
│ │ ├── init.go
│ │ └── system.go
│ ├── system-entry
│ │ └── system_info.go
│ ├── system-store
│ │ ├── init.go
│ │ └── system_info.go
│ └── system.go
├── user
│ ├── user-dto
│ │ ├── access.go
│ │ └── user_info.go
│ ├── user-entry
│ │ └── user_info.go
│ ├── user-mock
│ │ └── user_mock.go
│ ├── user-model
│ │ ├── session.go
│ │ └── user_info.go
│ ├── user-service
│ │ ├── init.go
│ │ ├── session.go
│ │ ├── user_cache.go
│ │ └── user_info.go
│ ├── user-store
│ │ ├── init.go
│ │ └── user_info.go
│ └── user.go
├── variable
│ ├── service.go
│ ├── variable-controller
│ │ ├── cluster_variable.go
│ │ ├── global_variable.go
│ │ └── module.go
│ ├── variable-dto
│ │ └── global_variable.go
│ ├── variable-entry
│ │ ├── variable_cluster.go
│ │ ├── variable_history.go
│ │ ├── variable_publish_history.go
│ │ ├── variable_runtime.go
│ │ ├── variable_version.go
│ │ └── variables.go
│ ├── variable-model
│ │ ├── cluster_variable.go
│ │ └── global_variable.go
│ ├── variable-service
│ │ ├── cluster_variable.go
│ │ ├── global_variable.go
│ │ └── init.go
│ └── variable-store
│ │ ├── cluster_variable.go
│ │ ├── global_variable.go
│ │ ├── init.go
│ │ ├── variable_history.go
│ │ ├── variable_publish_history.go
│ │ ├── variable_publish_version.go
│ │ └── variable_runtime.go
└── webhook
│ ├── controller
│ ├── module.go
│ └── webhook.go
│ └── dto
│ └── webhook.go
├── plugin
├── go-plugin
│ ├── example
│ │ ├── .gitignore
│ │ ├── client.go
│ │ ├── config.yml
│ │ └── plugin
│ │ │ ├── .gitignore
│ │ │ └── plugin.go
│ ├── plugin-client
│ │ ├── client.go
│ │ └── cmd.go
│ ├── plugin
│ │ ├── config.go
│ │ ├── logger.go
│ │ ├── response.go
│ │ ├── server.go
│ │ └── server_keys.go
│ ├── proto
│ │ ├── gen.go
│ │ ├── plugin.pb.go
│ │ ├── plugin.proto
│ │ └── plugin_grpc.pb.go
│ └── shared
│ │ ├── config.go
│ │ └── handler.go
├── local
│ ├── cmd_unix.go
│ ├── cmd_win.go
│ ├── config.go
│ ├── define.go
│ ├── driver.go
│ ├── module.go
│ ├── plugin.go
│ ├── proxy-api.go
│ ├── proxy-home.go
│ └── proxy-middleware.go
└── remote
│ ├── config.go
│ ├── define.go
│ ├── driver.go
│ ├── module.go
│ ├── plugin.go
│ └── remote_apis.go
├── report
├── env.go
└── report.go
├── scripts
├── Dockerfile
├── README.md
├── build.sh
├── docker_build.sh
├── docker_publish.sh
├── init.sh
├── prefix.sh
└── resource
│ ├── config.yml.tpl
│ ├── docker_run.sh
│ ├── install.sh
│ └── run.sh
└── store
├── base_history.go
├── base_publish_history.go
├── base_runtime.go
├── basekind.go
├── init.go
├── page.go
├── register.go
├── store.go
└── store_mysql
└── db-mysql.go
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 | contact_links:
3 | - name: APINTO Dashboard Discussion Forum
4 | url: https://github.com/eolinker/apinto-dashboard/discussions
5 | about: Please ask and answer questions here.
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /apinto-dashboard/
2 | /business/
3 | *.zip
4 | /work/
5 |
6 | /batch-publish/
7 | /migrate/
8 |
--------------------------------------------------------------------------------
/app/apserver/.gitignore:
--------------------------------------------------------------------------------
1 | /apserver
2 | config.yml
3 | config_dev.yml
4 | access.yml
5 | role.yml
6 | apinto_plugin.yml
7 | /config.yml
8 | /apinto_enterprise
9 | work
10 | /plugin/
11 | *.exe
12 | /local/
13 |
--------------------------------------------------------------------------------
/app/apserver/embed_plugin.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | _ "github.com/eolinker/apinto-dashboard/initialize/navigation"
5 | _ "github.com/eolinker/apinto-dashboard/initialize/plugin-group"
6 | _ "github.com/eolinker/apinto-dashboard/initialize/plugins"
7 | )
8 |
--------------------------------------------------------------------------------
/app/dynamic-module/.gitignore:
--------------------------------------------------------------------------------
1 | *.zip
--------------------------------------------------------------------------------
/app/dynamic-module/file-access-log/文件日志.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/app/dynamic-module/file-access-log/文件日志.png
--------------------------------------------------------------------------------
/app/dynamic-module/http-access-log/HTTP日志.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/app/dynamic-module/http-access-log/HTTP日志.png
--------------------------------------------------------------------------------
/app/dynamic-module/influxdb/InfluxDB配置.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/app/dynamic-module/influxdb/InfluxDB配置.png
--------------------------------------------------------------------------------
/app/dynamic-module/influxdb/README.md:
--------------------------------------------------------------------------------
1 | ## 基本介绍
2 | InfluxDB是专门为收集、存储、处理和可视化时间序列数据而构建的平台。时间序列数据是按时间顺序编制索引的一系列数据点。数据点通常由同一来源的连续测量组成,用于跟踪随时间的变化。该插件支持配置InfluxDB v2服务端信息,InfluxDB是监控告警的数据源之一。
3 | ## 功能特性
4 | - 配置InfluxDB v2服务端信息。
5 | - 收集网关请求信息,作为监控告警插件依赖接入,监控告警的数据源之一。
6 | ## 更新日志
7 | ### V1.0(2023-4-30)
8 | - 插件上线
--------------------------------------------------------------------------------
/app/dynamic-module/kafka-access-log/Kafka日志.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/app/dynamic-module/kafka-access-log/Kafka日志.png
--------------------------------------------------------------------------------
/app/dynamic-module/nsqd-access-log/NSQ日志.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/app/dynamic-module/nsqd-access-log/NSQ日志.png
--------------------------------------------------------------------------------
/app/dynamic-module/package.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ORG_PATH=`pwd`
4 | for file in `ls .`
5 | do
6 | if [[ "$file" == "package.sh" ]];then
7 | continue
8 | fi
9 | cd $ORG_PATH/$file
10 | rm -f *.zip
11 | zip -r -o $file.zip *
12 | done
13 |
14 | cd $ORG_PATH
--------------------------------------------------------------------------------
/app/dynamic-module/redis/README.md:
--------------------------------------------------------------------------------
1 | ## 基本介绍
2 | Redis是一个开源(BSD许可)的内存数据结构存储,用作数据库、缓存、消息代理和流媒体引擎。Redis提供数据结构,如字符串、散列、列表、集合、带范围查询的排序集合、位图、超日志、地理空间索引和流。Redis具有内置复制、Lua脚本、LRU驱逐、事务和不同级别的磁盘持久性,并通过Redis Sentinel和Redis Cluster的自动分区提供高可用性。该插件支持配置Redis Cluster信息,从而使Apinto节点接入Redis。
3 | ## 功能特性
4 | - 配置Redis Cluster信息,帮助Apinto节点接入Redis。
5 | - Apinto多个策略、插件依赖Redis,配置Redis后,使用Redis作为缓存数据库。
6 | ## 更新日志
7 | ### V1.0(2023-4-30)
8 | - 插件上线
--------------------------------------------------------------------------------
/app/dynamic-module/redis/Redis配置.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/app/dynamic-module/redis/Redis配置.png
--------------------------------------------------------------------------------
/app/dynamic-module/syslog-access-log/SYSLOG日志.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/app/dynamic-module/syslog-access-log/SYSLOG日志.png
--------------------------------------------------------------------------------
/client/v1/client_test.go:
--------------------------------------------------------------------------------
1 | package v1
2 |
3 | import (
4 | "fmt"
5 | "testing"
6 | )
7 |
8 | func TestWorker(t *testing.T) {
9 |
10 | client, err := NewClient([]string{"http://172.27.75.146:9400"})
11 |
12 | err = client.ForApp().Patch("lGmKT7RvbhCRlhI5", map[string]interface{}{"disable": true})
13 | fmt.Println(err)
14 |
15 | //key, err := client.ForVariable().GetByKey(namespace, "test1")
16 | //if err != nil {
17 | // panic(err)
18 | //}
19 | //fmt.Println(key)
20 |
21 | //all, err := client.ForVariable().GetAll()
22 | //if err != nil {
23 | // panic(err)
24 | //}
25 | //fmt.Println(all)
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/client/v1/initialize/plugin/black_extended.yml:
--------------------------------------------------------------------------------
1 | -
2 | id: eolinker.com:apinto:monitor
3 | name: monitor
4 | status: global
5 | -
6 | id: eolinker.com:apinto:plugin_app
7 | name: app
8 | status: global
9 | -
10 | id: eolinker.com:apinto:strategy-plugin-visit
11 | name: strategy_visit
12 | status: global
13 | -
14 | id: eolinker.com:apinto:strategy-plugin-grey
15 | name: strategy_grey
16 | status: global
17 | -
18 | id: eolinker.com:apinto:strategy-plugin-limiting
19 | name: strategy_limiting
20 | status: global
21 | config:
22 | cache: redis@output
23 | -
24 | id: eolinker.com:apinto:strategy-plugin-fuse
25 | name: strategy_fuse
26 | status: global
27 | config:
28 | cache: redis@output
29 | -
30 | id: eolinker.com:apinto:strategy-plugin-cache
31 | name: strategy_cache
32 | status: global
33 | config:
34 | cache: redis@output
--------------------------------------------------------------------------------
/client/v1/initialize/plugin/global.go:
--------------------------------------------------------------------------------
1 | package plugin
2 |
3 | import (
4 | _ "embed"
5 |
6 | v1 "github.com/eolinker/apinto-dashboard/client/v1"
7 | "gopkg.in/yaml.v3"
8 | )
9 |
10 | //go:embed apinto_plugin.yml
11 | var pluginData []byte
12 |
13 | var pluginConf []*v1.GlobalPlugin
14 |
15 | func init() {
16 | var err error
17 |
18 | pc := make([]*v1.GlobalPlugin, 0)
19 | err = yaml.Unmarshal(pluginData, &pc)
20 | if err != nil {
21 | panic(err)
22 | }
23 |
24 | pluginConf = pc
25 | }
26 |
27 | func GetGlobalPluginConf() []*v1.GlobalPlugin {
28 | return pluginConf
29 | }
30 |
--------------------------------------------------------------------------------
/client/v1/proxy.go:
--------------------------------------------------------------------------------
1 | package v1
2 |
3 | type JsonMarshalProxy []byte
4 |
5 | func (j *JsonMarshalProxy) MarshalJSON() ([]byte, error) {
6 | return *j, nil
7 | }
8 |
--------------------------------------------------------------------------------
/client/v2/cluster.go:
--------------------------------------------------------------------------------
1 | package v2
2 |
3 | type Cluster struct {
4 | Cluster string `yaml:"cluster"`
5 | Nodes []*Node `yaml:"nodes"`
6 | }
7 |
8 | type Node struct {
9 | Id string `json:"id"`
10 | Name string `json:"name"`
11 | Peer []string `yaml:"peer"`
12 | Admin []string `json:"admin"`
13 | Server []string `json:"server"`
14 | Leader bool `json:"leader"`
15 | }
16 |
--------------------------------------------------------------------------------
/client/v2/status.go:
--------------------------------------------------------------------------------
1 | package v2
2 |
3 | const (
4 | StatusOffline = "未发布"
5 | StatusPre = "待发布"
6 | StatusOnline = "已发布"
7 | )
8 |
--------------------------------------------------------------------------------
/common/base64.go:
--------------------------------------------------------------------------------
1 | package common
2 |
3 | import (
4 | "encoding/base64"
5 | )
6 |
7 | //Base64Encode 加密
8 | func Base64Encode(src []byte) string {
9 | return base64.StdEncoding.EncodeToString(src)
10 | }
11 |
12 | //Base64Decode 解密
13 | func Base64Decode(src string) ([]byte, error) {
14 | // 对上面的编码结果进行base64解码
15 | decodeBytes, err := base64.StdEncoding.DecodeString(src)
16 | if err != nil {
17 | return nil, err
18 | }
19 | return decodeBytes, nil
20 | }
21 |
--------------------------------------------------------------------------------
/common/const.go:
--------------------------------------------------------------------------------
1 | package common
2 |
--------------------------------------------------------------------------------
/common/email.go:
--------------------------------------------------------------------------------
1 | package common
2 |
3 | import (
4 | "crypto/tls"
5 | "gopkg.in/gomail.v2"
6 | )
7 |
8 | func NewSmtp(host string, port int, protocol string, account string, password string, email string) *Smtp {
9 | d := gomail.NewDialer(host, port, account, password)
10 | if protocol == "ssl" || protocol == "tls" {
11 | d.SSL = true
12 | d.TLSConfig = &tls.Config{ServerName: host}
13 | }
14 | return &Smtp{dialer: d, email: email}
15 | }
16 |
17 | type Smtp struct {
18 | email string
19 | dialer *gomail.Dialer
20 | }
21 |
22 | func (s *Smtp) SendTo(sends []string, title, msg string) error {
23 |
24 | m := gomail.NewMessage()
25 | m.SetHeader("From", s.email)
26 | m.SetHeader("To", sends...)
27 | m.SetHeader("Subject", title)
28 | m.SetBody("text/html;charset=utf-8", msg)
29 |
30 | return s.dialer.DialAndSend(m)
31 | }
32 |
--------------------------------------------------------------------------------
/common/error.go:
--------------------------------------------------------------------------------
1 | package common
2 |
3 | import (
4 | "errors"
5 | "strings"
6 | )
7 |
8 | var (
9 | ClusterNotExist = errors.New("cluster does not exist")
10 | )
11 |
12 | const workerNotExistErrStr = "worker-data not exits"
13 |
14 | // CheckWorkerNotExist 检查报错信息是否为worker实例不存在
15 | func CheckWorkerNotExist(err error) error {
16 | if err != nil && strings.Contains(err.Error(), workerNotExistErrStr) {
17 | return nil
18 | }
19 | return err
20 | }
21 |
--------------------------------------------------------------------------------
/common/float64.go:
--------------------------------------------------------------------------------
1 | package common
2 |
3 | import (
4 | "fmt"
5 | "strconv"
6 | )
7 |
8 | // FormatFloat64 float64保留places位小数
9 | func FormatFloat64(f float64, places int) float64 {
10 | formatStr := "%." + strconv.Itoa(places) + "f"
11 | f64, _ := strconv.ParseFloat(fmt.Sprintf(formatStr, f), 64)
12 | return f64
13 | }
14 |
--------------------------------------------------------------------------------
/common/http.go:
--------------------------------------------------------------------------------
1 | package common
2 |
3 | import (
4 | "io"
5 | "net/http"
6 | "strings"
7 | )
8 |
9 | // NewRequest body = strings.NewReader(string(by))
10 | func NewRequest(method, url string, body io.Reader) (by []byte, err error) {
11 | method = strings.ToUpper(method)
12 | client := &http.Client{}
13 | req, err := http.NewRequest(method, url, body)
14 | req.Header.Add("Content-Type", "application/json;charset=UTF-8")
15 | defer req.Body.Close()
16 | if err != nil {
17 | return nil, err
18 | }
19 | resp, err := client.Do(req)
20 | if err != nil {
21 | return nil, err
22 | }
23 | defer resp.Body.Close()
24 | return io.ReadAll(resp.Body)
25 | }
26 |
--------------------------------------------------------------------------------
/common/json.go:
--------------------------------------------------------------------------------
1 | package common
2 |
3 | import (
4 | "encoding/json"
5 | "errors"
6 | "github.com/xeipuuv/gojsonschema"
7 | "io"
8 | )
9 |
10 | func DecodeJSON(r io.Reader, obj any) error {
11 | decoder := json.NewDecoder(r)
12 | return decoder.Decode(obj)
13 | }
14 |
15 | func JsonSchemaValid(schema, data string) error {
16 | // 解析JSON Schema
17 | loader := gojsonschema.NewStringLoader(schema)
18 | schemaDocument, err := gojsonschema.NewSchema(loader)
19 | if err != nil {
20 | return err
21 | }
22 |
23 | // 解析待校验的JSON数据
24 | documentLoader := gojsonschema.NewStringLoader(data)
25 | result, err := schemaDocument.Validate(documentLoader)
26 | if err != nil {
27 | return err
28 | }
29 | if result.Valid() {
30 | return nil
31 | }
32 | return errors.New(result.Errors()[0].String())
33 | }
34 |
--------------------------------------------------------------------------------
/common/map.go:
--------------------------------------------------------------------------------
1 | package common
2 |
3 | type Map map[string]any
4 |
--------------------------------------------------------------------------------
/common/md5.go:
--------------------------------------------------------------------------------
1 | package common
2 |
3 | import (
4 | "crypto/md5"
5 | "encoding/hex"
6 | )
7 |
8 | func Md5(str string) string {
9 | h := md5.New()
10 | h.Write([]byte(str))
11 | return hex.EncodeToString(h.Sum(nil))
12 | }
13 |
--------------------------------------------------------------------------------
/common/panic.go:
--------------------------------------------------------------------------------
1 | package common
2 |
3 | import (
4 | "bytes"
5 | "fmt"
6 | "runtime"
7 | )
8 |
9 | func PanicTrace(err interface{}) string {
10 | buf := new(bytes.Buffer)
11 | _, _ = fmt.Fprintf(buf, "%v\n", err)
12 | for i := 1; ; i++ {
13 | pc, file, line, ok := runtime.Caller(i)
14 | if !ok {
15 | break
16 | }
17 | _, _ = fmt.Fprintf(buf, "%s:%d (0x%x)\n", file, line, pc)
18 | }
19 | return buf.String()
20 | }
21 |
--------------------------------------------------------------------------------
/common/path.go:
--------------------------------------------------------------------------------
1 | package common
2 |
3 | import (
4 | "errors"
5 | "net/url"
6 | "os"
7 | "path/filepath"
8 | "strings"
9 | )
10 |
11 | func CheckAndFormatPath(path string) (string, error) {
12 | decodedPath, err := url.PathUnescape(path)
13 | if err != nil {
14 | return path, errors.New("Unescape fail. ")
15 | }
16 | if CheckPathContainsIPPort(decodedPath) {
17 | return path, errors.New("path is illegal. ")
18 | }
19 | if idx := strings.Index(decodedPath, "?"); idx != -1 {
20 | return path, errors.New("can't contain ?. ")
21 | }
22 | return decodedPath, nil
23 | }
24 |
25 | func GetCurrentPath() (string, error) {
26 | execPath, err := os.Executable()
27 | if err != nil {
28 | return "", err
29 | }
30 | currentPath, err := filepath.EvalSymlinks(filepath.Dir(execPath))
31 | if err != nil {
32 | return "", err
33 | }
34 | return currentPath, nil
35 | }
36 |
--------------------------------------------------------------------------------
/common/restful/builder.go:
--------------------------------------------------------------------------------
1 | package restful
2 |
3 | import (
4 | "net/http"
5 | "net/url"
6 | )
7 |
8 | type requestCore struct {
9 | *builderCore
10 | header http.Header
11 | query url.Values
12 | }
13 |
14 | type builderCore struct {
15 | Config
16 | path PathGen
17 | method string
18 | }
19 |
20 | func newBuilderCore(config Config, method string, path string) builderCore {
21 | return builderCore{Config: config, path: createPath(path), method: method}
22 | }
23 |
24 | func (b *builderCore) build() *requestCore {
25 |
26 | return &requestCore{builderCore: b, header: b.header.Clone(), query: cloneValues(b.query)}
27 |
28 | }
29 | func (b *builderCore) Reset(c Config) {
30 | b.Config = c
31 | }
32 |
--------------------------------------------------------------------------------
/common/restful/data.go:
--------------------------------------------------------------------------------
1 | package restful
2 |
3 | type ResponseData[D any] struct {
4 | Code int `json:"code,omitempty"`
5 | Message string `json:"message,omitempty"`
6 | RequestId string `json:"requestId,omitempty"`
7 | Success bool `json:"success,omitempty"`
8 | Data *D `json:"data"`
9 | }
10 | type Response struct {
11 | Code int `json:"code,omitempty"`
12 | Message string `json:"message,omitempty"`
13 | RequestId string `json:"requestId,omitempty"`
14 | Success bool `json:"success,omitempty"`
15 | }
16 |
--------------------------------------------------------------------------------
/common/slice.go:
--------------------------------------------------------------------------------
1 | package common
2 |
3 | // ListPage 返回截取下标 [i:y]
4 | //
5 | // if i == 0 && y == 0 {
6 | // "分页错误"
7 | // }
8 | // list[i:y]
9 | func ListPage(pageNo, pageSize int, length int) (int, int) {
10 | if pageNo == 0 {
11 | pageNo = 1
12 | }
13 | if (pageNo-1)*pageSize > length {
14 | return 0, 0
15 | }
16 | if pageNo == 1 {
17 | if pageNo*pageSize > length {
18 | return 0, (pageSize * pageNo) - ((pageSize * pageNo) - length)
19 | }
20 | return 0, pageSize * pageNo
21 | } else {
22 | if pageNo*pageSize > length {
23 | return pageSize * (pageNo - 1), (pageSize * pageNo) - ((pageSize * pageNo) - length)
24 | } else {
25 | return pageSize * (pageNo - 1), pageSize * pageNo
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/common/time.go:
--------------------------------------------------------------------------------
1 | package common
2 |
3 | import "time"
4 |
5 | const formatTime = "2006-01-02 15:04:05"
6 |
7 | func TimeToStr(t time.Time) string {
8 | if t.IsZero() {
9 | return "-"
10 | }
11 | return t.Format(formatTime)
12 | }
13 |
14 | func StrToTime(t string) time.Time {
15 | location, _ := time.ParseInLocation(formatTime, t, time.Local)
16 | return location
17 | }
18 |
19 | func GenVersion(now time.Time) string {
20 | return now.Format("20060102150405")
21 | }
22 |
--------------------------------------------------------------------------------
/common/yml.go:
--------------------------------------------------------------------------------
1 | package common
2 |
3 | import (
4 | "gopkg.in/yaml.v3"
5 | io "io"
6 | )
7 |
8 | func DecodeYAML(r io.Reader, obj any) error {
9 | decoder := yaml.NewDecoder(r)
10 | return decoder.Decode(obj)
11 | }
12 |
--------------------------------------------------------------------------------
/config/dir.go:
--------------------------------------------------------------------------------
1 | package config
2 |
3 | import (
4 | "os"
5 | "path/filepath"
6 | )
7 |
8 | //GetLastAbsPathByExecutable 获取执行程序所在的上一层级目录的绝对路径
9 | func GetLastAbsPathByExecutable() (string, error) {
10 | exePath, err := os.Executable()
11 | if err != nil {
12 | return "", err
13 | }
14 | res, _ := filepath.EvalSymlinks(exePath)
15 | res = filepath.Dir(res) //获取程序所在目录
16 | res = filepath.Dir(res) //获取程序所在上一层级目录
17 | return res, nil
18 | }
19 |
--------------------------------------------------------------------------------
/config/redis.go:
--------------------------------------------------------------------------------
1 | package config
2 |
3 | import (
4 | "context"
5 | "time"
6 |
7 | "github.com/eolinker/apinto-dashboard/cache"
8 | "github.com/redis/go-redis/v9"
9 | )
10 |
11 | func InitRedis() {
12 |
13 | client := redis.NewClusterClient(&redis.ClusterOptions{
14 | Addrs: getRedisAddr(),
15 | Username: getRedisUserName(),
16 | Password: getRedisPwd(),
17 | })
18 |
19 | timeout, cancelFunc := context.WithTimeout(context.Background(), time.Second)
20 | defer cancelFunc()
21 | if err := client.Ping(timeout).Err(); err != nil {
22 | _ = client.Close()
23 | panic(err)
24 | }
25 |
26 | cache.InitCache(client)
27 | }
28 |
--------------------------------------------------------------------------------
/config/store.go:
--------------------------------------------------------------------------------
1 | //go:build !mysql
2 | // +build !mysql
3 |
4 | package config
5 |
6 | func InitDb() {
7 | return
8 | }
9 |
--------------------------------------------------------------------------------
/controller/.gitignore:
--------------------------------------------------------------------------------
1 | /dist/
--------------------------------------------------------------------------------
/controller/audit.go:
--------------------------------------------------------------------------------
1 | package controller
2 |
3 | import (
4 | audit_model "github.com/eolinker/apinto-dashboard/modules/audit/audit-model"
5 | "github.com/gin-gonic/gin"
6 | )
7 |
8 | type LogOperateType audit_model.LogOperateType
9 |
10 | func (l LogOperateType) Handler(ginCtx *gin.Context) {
11 | ginCtx.Set(Operate, int(l))
12 | }
13 |
--------------------------------------------------------------------------------
/controller/gin_context.go:
--------------------------------------------------------------------------------
1 | package controller
2 |
3 | import (
4 | "context"
5 | "encoding/json"
6 | "github.com/gin-gonic/gin"
7 | )
8 |
9 | func SetGinContextAuditObject(ctx context.Context, v interface{}) {
10 | if ginCtx, ok := ctx.(*gin.Context); ok {
11 | objectData, _ := json.Marshal(v)
12 | ginCtx.Set(AuditObject, string(objectData))
13 |
14 | }
15 |
16 | }
17 |
18 | func GetGinContextAuditObject(ginCtx *gin.Context) (value any, exists bool) {
19 |
20 | return ginCtx.Get(AuditObject)
21 |
22 | }
23 |
24 | func GetNamespaceId(ginCtx *gin.Context) int {
25 | id := ginCtx.GetInt(NamespaceId)
26 | if id == 0 {
27 | return 1
28 | }
29 | return id
30 | }
31 |
--------------------------------------------------------------------------------
/controller/users/user.go:
--------------------------------------------------------------------------------
1 | package users
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/controller"
5 | "github.com/eolinker/apinto-dashboard/modules/user"
6 | "github.com/eolinker/eosc/common/bean"
7 | "github.com/gin-gonic/gin"
8 | )
9 |
10 | const (
11 | userIdKey = "userId"
12 | )
13 |
14 | var (
15 | userInfoService user.IUserInfoService
16 | )
17 |
18 | func init() {
19 | bean.Autowired(&userInfoService)
20 | }
21 | func GetUserId(ginCtx *gin.Context) int {
22 |
23 | id := ginCtx.GetInt(userIdKey)
24 | if id != 0 {
25 | return id
26 | }
27 |
28 | userName := ginCtx.GetString(controller.UserName)
29 | if userName == "" {
30 | return 0
31 | }
32 | userInfo, err := userInfoService.GetUserInfoByName(ginCtx, userName)
33 | if err != nil {
34 | return 0
35 | }
36 | ginCtx.Set(userIdKey, userInfo.Id)
37 | return userInfo.Id
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/enum/cluster_config.go:
--------------------------------------------------------------------------------
1 | package enum
2 |
--------------------------------------------------------------------------------
/enum/cluster_node_status.go:
--------------------------------------------------------------------------------
1 | package enum
2 |
3 | import "fmt"
4 |
5 | type ClusterNodeStatus int
6 |
7 | const (
8 | ClusterNodeStatusNone = iota
9 | ClusterNodeStatusNotRunning
10 | ClusterNodeStatusRunning
11 | ClusterNodeStatusAll
12 | )
13 |
14 | var (
15 | clusterNodeStatusNames = map[ClusterNodeStatus]string{
16 | ClusterNodeStatusNone: "NONE",
17 | ClusterNodeStatusNotRunning: "NOTRUNNING", //未运行
18 | ClusterNodeStatusRunning: "RUNNING", //运行中
19 | }
20 | )
21 |
22 | func (e ClusterNodeStatus) MarshalJSON() ([]byte, error) {
23 | return []byte(fmt.Sprint("\"", e.String(), "\"")), nil
24 | }
25 |
26 | func (e ClusterNodeStatus) String() string {
27 | if e >= ClusterNodeStatusAll {
28 | return "unknown"
29 | }
30 | return clusterNodeStatusNames[e]
31 | }
32 |
--------------------------------------------------------------------------------
/enum/cluster_status.go:
--------------------------------------------------------------------------------
1 | package enum
2 |
3 | import "fmt"
4 |
5 | type ClusterStatus int
6 |
7 | const (
8 | ClusterStatusNone = iota
9 | ClusterStatusNormal
10 | ClusterStatusPartiallyNormal
11 | ClusterStatusAbnormal
12 | ClusterStatusAbnormalAll
13 | )
14 |
15 | var (
16 | clusterStatusNames = map[ClusterStatus]string{
17 | ClusterStatusNone: "NONE",
18 | ClusterStatusNormal: "NORMAL",
19 | ClusterStatusPartiallyNormal: "PARTIALLY_NORMAL",
20 | ClusterStatusAbnormal: "ABNORMAL",
21 | }
22 | clusterStatusIndex = map[string]ClusterStatus{}
23 | )
24 |
25 | func (e ClusterStatus) MarshalJSON() ([]byte, error) {
26 | return []byte(fmt.Sprint("\"", e.String(), "\"")), nil
27 | }
28 |
29 | func (e ClusterStatus) String() string {
30 | if e >= ClusterStatusAbnormalAll {
31 | return "unknown"
32 | }
33 | return clusterStatusNames[e]
34 | }
35 |
--------------------------------------------------------------------------------
/enum/common.go:
--------------------------------------------------------------------------------
1 | package enum
2 |
3 | const (
4 | HttpALL = "ALL"
5 | HttpGET = "GET"
6 | HttpPOST = "POST"
7 | HttpPUT = "PUT"
8 | HttpDELETE = "DELETE"
9 | HttpPATCH = "PATCH"
10 | HttpHEADER = "HEADER"
11 | HttpOPTIONS = "OPTIONS"
12 | )
13 |
--------------------------------------------------------------------------------
/enum/keyword.go:
--------------------------------------------------------------------------------
1 | package enum
2 |
3 | import "github.com/eolinker/apinto-dashboard/modules/strategy/config"
4 |
5 | var Keyword = map[string]struct{}{config.FilterValuesALL: {}, config.FilterApplication: {}, config.FilterApi: {}, config.FilterPath: {}, config.FilterService: {}, config.FilterMethod: {}, config.FilterIP: {}}
6 |
--------------------------------------------------------------------------------
/frontend/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | browser: true,
4 | es2021: true
5 | },
6 | extends: ['standard'],
7 | parser: '@typescript-eslint/parser',
8 | parserOptions: {
9 | ecmaVersion: 12,
10 | sourceType: 'module'
11 | },
12 | plugins: ['@typescript-eslint'],
13 | rules: {
14 | 'no-unused-vars': 'off',
15 | '@typescript-eslint/no-unused-vars': 2,
16 | 'no-useless-constructor': 'off',
17 | '@typescript-eslint/no-useless-constructor': 'warn'
18 | },
19 | globals: {
20 | angular: true,
21 | page: true,
22 | describe: true,
23 | it: true,
24 | test: true,
25 | expect: true,
26 | beforeEach: true,
27 | jest: true
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/frontend/.npmrc:
--------------------------------------------------------------------------------
1 | save=true
2 | save-exact=true
3 | registry=https://registry.npmmirror.com
4 |
--------------------------------------------------------------------------------
/frontend/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "semi": false,
4 | "trailingComma": "none",
5 | "bracketSpacing": true
6 | }
--------------------------------------------------------------------------------
/frontend/.yarnrc:
--------------------------------------------------------------------------------
1 | save=true
2 | save-exact=true
3 | registry=https://registry.npmmirror.com
4 |
--------------------------------------------------------------------------------
/frontend/README.md:
--------------------------------------------------------------------------------
1 | # Apinto
2 |
3 | ## 从npm切换成yarn(首次切换需要,切换后请直接从安装依赖开始
4 | `npm install yarn -g ` 安装yarn
5 |
6 | `yarn versions` 验证yarn版本,确认是否安装好
7 |
8 | `rm -rf node_modules` 删除原先的node_modules文件
9 |
10 | `yarn` 重新安装,此处可能要求选择eo-ng*依赖包的版本,可以直接用enter键选择最新版本
11 |
12 | `yarn run dll` 重新编译dll,此处可能出现找不到的报错,可以略过
13 |
14 | `yarn run deploy` 此处可能出现找不到的报错,可以略过
15 |
16 | `yarn config set registry https://registry.npm.taobao.org` 将安装源切换为淘宝镜像源,会快一些
17 |
18 | ## 安装依赖
19 | `yarn install --legacy-peer-deps`
20 |
21 | ## 打包
22 | `yarn build`
23 |
24 | ## 本地运行
25 | 如需本地单独运行前端项目,
26 |
27 | 1. 先移除frontend文件夹根路径的.angular.json文件里的deployUrl配置(如与apinto网关一同运行,则需要恢复该配置)
28 |
29 | 2. 运行 `yarn start:demo`,该命令将为您在本地运行前端项目,其中请求接口将通过代理连接到 demo-dashboard.apinto.com, 账号信息可查看apinto项目的readme文档
30 |
31 | 3. 如您已自行部署好apinto后端,可以通过修改proxy.config.demo.json文件里的地址,将请求接口地址改成后端部署地址;如不需要代理,可删除package.json文件中,`yarn start:demo`语句里的代理配置
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/component/iframe/iframe.component.html:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/component/intelligent-plugin/create/create.component.html:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/component/intelligent-plugin/layout/layout.component.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/component/intelligent-plugin/layout/layout.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core'
2 | @Component({
3 | selector: 'eo-ng-intelligent-plugin-layout',
4 | templateUrl: './layout.component.html',
5 | styles: [
6 | ]
7 | })
8 | export class EoIntelligentPluginLayoutComponent {
9 | }
10 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/component/intelligent-plugin/types/conf.ts:
--------------------------------------------------------------------------------
1 | import { THEAD_TYPE } from 'eo-ng-table'
2 |
3 | export const EoIntelligentPluginDefaultThead:THEAD_TYPE[] = [
4 | {
5 | title: '名称',
6 | left: true
7 | },
8 | { title: 'ID' },
9 | { title: '描述' },
10 | { title: '状态' },
11 | { title: '更新人' },
12 | { title: '更新时间' },
13 | {
14 | title: '操作',
15 | right: true
16 | }
17 | ]
18 |
19 | export const PublishTableHeadName:THEAD_TYPE[] = [
20 | { type: 'checkbox' },
21 | { title: '集群' },
22 | { title: '状态' },
23 | { title: '更新人' },
24 | { title: '更新时间' }
25 | ]
26 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/component/user-avatar/user-avatar.component.html:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |

12 |
{{ nickName }}
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/component/user-avatar/user-avatar.component.scss:
--------------------------------------------------------------------------------
1 | :host ::ng-deep {
2 | eo-ng-dropdown button {
3 | border: none !important;
4 | background-color: transparent !important;
5 | width: auto;
6 | height: 28px !important;
7 | line-height: 28px !important;
8 | }
9 |
10 | .name-width {
11 | height: 0;
12 | margin-left: 48px;
13 | }
14 |
15 | .avatar {
16 | color: var(--MAIN_THEME_BG);
17 | }
18 |
19 | .iconfont {
20 | font-size: 32px;
21 | color: #dadadb;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/constant/form.ts:
--------------------------------------------------------------------------------
1 | // 表单的常用方法
2 | import { FormGroup } from '@angular/forms'
3 | // 表单初始化
4 |
5 | // 表单赋值
6 | export function setFormValue (form:FormGroup, data:{[key:string]:any}):void {
7 | Object.keys(form.controls).forEach(key => {
8 | if (form.controls[key] instanceof FormGroup) {
9 | setFormValue(form.controls[key] as FormGroup, data[key])
10 | } else {
11 | form.controls[key].setValue(data[key])
12 | }
13 | })
14 | }
15 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/custom-preloading-strategy.ts:
--------------------------------------------------------------------------------
1 | import { PreloadingStrategy, Route } from '@angular/router'
2 | import { Observable, of, delay, mergeMap } from 'rxjs'
3 |
4 | export class CustomPreloadingStrategy implements PreloadingStrategy {
5 | preload (route:Route, fn:()=> Observable): Observable {
6 | return of(true).pipe(
7 | delay(1000),
8 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
9 | mergeMap((_: boolean) => fn())
10 | )
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/directive/auto-focus.directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, ElementRef } from '@angular/core'
2 |
3 | @Directive({
4 | selector: '[eoNgAutoFocus]'
5 | })
6 | export class AutoFocusDirective {
7 | constructor (
8 | private el:ElementRef) { }
9 |
10 | ngAfterViewInit ():void {
11 | setTimeout(
12 | () => {
13 | this.el.nativeElement.focus()
14 | }, 0
15 | )
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/directive/directive.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core'
2 | import { CommonModule } from '@angular/common'
3 | import { UserAccessDirective } from './user-access.directive'
4 | import { TreeDragDirective } from './tree-drag.directive'
5 | import { RowExpandButtonDirective } from './row-expand-button.directive'
6 | import { AutoFocusDirective } from './auto-focus.directive'
7 | import { EoNgScrollDomDirective } from './eo-ng-scroll-dom.directive'
8 |
9 | @NgModule({
10 | declarations: [UserAccessDirective, TreeDragDirective, RowExpandButtonDirective, AutoFocusDirective, EoNgScrollDomDirective],
11 | imports: [
12 | CommonModule
13 | ],
14 | exports: [
15 | UserAccessDirective, TreeDragDirective,
16 | RowExpandButtonDirective, AutoFocusDirective,
17 | EoNgScrollDomDirective
18 | ]
19 | })
20 | export class DirectiveModule { }
21 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/api/api-list/message/http-message/http-message.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core'
2 | import { ApiMessageComponent } from '../message.component'
3 |
4 | @Component({
5 | selector: 'eo-ng-api-http-message',
6 | template: `
7 |
8 | `,
9 | styles: [
10 | ]
11 | })
12 | export class ApiHttpMessageComponent extends ApiMessageComponent {
13 | }
14 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/api/api-list/message/websocket-message/websocket-message.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core'
2 | import { ApiMessageComponent } from '../message.component'
3 |
4 | @Component({
5 | selector: 'eo-ng-api-websocket-message',
6 | template: `
7 |
8 |
9 | `,
10 | styles: [
11 | ]
12 | })
13 | export class ApiWebsocketMessageComponent extends ApiMessageComponent {
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/api/api-list/publish/batch/result.component.html:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/api/plugin/list/list.component.html:
--------------------------------------------------------------------------------
1 |
2 |
15 |
16 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/api/plugin/plugin.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core'
2 |
3 | @Component({
4 | selector: 'eo-ng-api-plugin-template',
5 | template: `
6 | `,
7 | styles: [
8 | ]
9 | })
10 | export class ApiPluginTemplateComponent {
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/api/plugin/publish/publish.component.html:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/api/router/router.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core'
2 |
3 | @Component({
4 | selector: 'app-router',
5 | template: `
6 |
7 | `,
8 | styles: [
9 | ]
10 | })
11 | export class RouterComponent {
12 | }
13 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/application/application.component.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: MengjieYang yangmengjie@eolink.com
3 | * @Date: 2022-08-17 23:42:52
4 | * @LastEditors: MengjieYang yangmengjie@eolink.com
5 | * @LastEditTime: 2022-08-24 00:34:31
6 | * @FilePath: /apinto/src/app/layout/application/application-management/application-management.component.ts
7 | * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
8 | */
9 | import { Component } from '@angular/core'
10 | @Component({
11 | selector: 'app-application-management',
12 | template: `
13 |
14 | `,
15 | styles: [
16 | `
17 | :host{
18 | height:100%;
19 | display:block;
20 | }`
21 | ]
22 | })
23 | export class ApplicationManagementComponent {
24 | }
25 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/application/message/message.component.html:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/audit-log/audit-log-routing.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core'
2 | import { RouterModule, Routes } from '@angular/router'
3 | import { AuditLogComponent } from './audit-log.component'
4 | import { AuditLogListComponent } from './list/list.component'
5 |
6 | const routes: Routes = [{
7 | path: '',
8 | component: AuditLogComponent,
9 | data: { id: '7' },
10 | children: [
11 | {
12 | path: '',
13 | component: AuditLogListComponent
14 | }
15 | ]
16 | }]
17 |
18 | @NgModule({
19 | imports: [RouterModule.forChild(routes)],
20 | exports: [RouterModule]
21 | })
22 | export class AuditLogRoutingModule { }
23 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/audit-log/audit-log.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core'
2 |
3 | @Component({
4 | selector: 'eo-ng-audit-log',
5 | template: `
6 |
7 | `,
8 | styles: [
9 | ]
10 | })
11 | export class AuditLogComponent {
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/audit-log/types/types.ts:
--------------------------------------------------------------------------------
1 | import { Operator } from '../../../constant/type'
2 | export interface AuditLogDetail{
3 | attr:string
4 | value:string
5 | }
6 |
7 | export interface AuditLogsData{
8 | id:number,
9 | operator:Operator,
10 | operateType: string,
11 | kind:string,
12 | time:string
13 | ip:string,
14 | [k:string]:any
15 | }
16 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/auth/update/update.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core'
2 |
3 | @Component({
4 | selector: 'eo-ng-auth-update',
5 | template: `
6 | `,
7 | styles: [
8 | ]
9 | })
10 | export class AuthUpdateComponent {}
11 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/deploy/cluster/cluster.component.html:
--------------------------------------------------------------------------------
1 |
9 |
10 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/deploy/cluster/cluster.component.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: MengjieYang yangmengjie@eolink.com
3 | * @Date: 2022-07-20 00:02:55
4 | * @LastEditors: MengjieYang yangmengjie@eolink.com
5 | * @LastEditTime: 2022-07-20 23:27:14
6 | * @FilePath: /apinto/src/app/layout/deploy-cluster/deploy-cluster.component.ts
7 | * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
8 | */
9 | import { Component } from '@angular/core'
10 |
11 | @Component({
12 | selector: 'eo-ng-deploy-cluster',
13 | templateUrl: './cluster.component.html',
14 | styles: [
15 | ]
16 | })
17 | export class DeployClusterComponent {
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/deploy/cluster/plugin/history/change/change.component.html:
--------------------------------------------------------------------------------
1 |
2 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/deploy/environment/environment.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core'
2 |
3 | @Component({
4 | selector: 'eo-ng-deploy-environment',
5 | template: `
6 |
7 | `,
8 | styles: [
9 | ''
10 | ]
11 | })
12 | export class DeployEnvironmentComponent {
13 | }
14 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/deploy/environment/types/types.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/frontend/projects/core/src/app/layout/deploy/environment/types/types.ts
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/deploy/plugin/deploy-plugin.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core'
2 |
3 | @Component({
4 | selector: 'eo-ng-deploy-plugin',
5 | template: `
6 |
7 | `,
8 | styles: [
9 | ]
10 | })
11 | export class DeployPluginComponent {
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/deploy/plugin/types/conf.ts:
--------------------------------------------------------------------------------
1 | import { THEAD_TYPE } from 'eo-ng-table'
2 |
3 | export const PluginsTableHeadName: THEAD_TYPE[] = [
4 | {
5 | type: 'sort',
6 | width: 40
7 | },
8 | { title: '插件名称' },
9 | { title: '扩展ID' },
10 | { title: '描述' },
11 | { title: '更新时间' },
12 | {
13 | title: '操作',
14 | right: true
15 | }
16 | ]
17 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/deploy/plugin/types/types.ts:
--------------------------------------------------------------------------------
1 | // 插件管理列表
2 | export type PluginItem = {
3 | name:string
4 | extended:string
5 | desc:string
6 | updateTime:string
7 | operator:string
8 | isDelete:boolean
9 | isBuilt:boolean
10 | }
11 |
12 | // 插件管理编辑
13 | export type PluginData = {
14 | name:string
15 | rely:string
16 | extended:string
17 | desc:string
18 | }
19 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/dynamic-demo/dynamic-demo.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core'
2 |
3 | @Component({
4 | selector: 'eo-ng-dynamic-demo',
5 | template: `
6 |
7 |
8 | `,
9 | styles: [
10 | ]
11 | })
12 | export class DynamicDemoComponent {
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/intelligent-plugin/create/create.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core'
2 | import { EoIntelligentPluginCreateComponent } from '../../../component/intelligent-plugin/create/create.component'
3 |
4 | @Component({
5 | selector: 'eo-ng-intelligent-plugin-create',
6 | templateUrl: '../../../component/intelligent-plugin/create/create.component.html',
7 | styles: [
8 | ]
9 | })
10 | export class IntelligentPluginCreateComponent extends EoIntelligentPluginCreateComponent {
11 | }
12 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/intelligent-plugin/intelligent-plugin-routing.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core'
2 | import { RouterModule, Routes } from '@angular/router'
3 | import { IntelligentPluginComponent } from './intelligent-plugin.component'
4 | import { IntelligentPluginLayoutComponent } from './layout/layout.component'
5 |
6 | const routes: Routes = [{
7 | path: '',
8 | component: IntelligentPluginComponent,
9 | children: [
10 | {
11 | path: ':moduleName',
12 | children: [{
13 | path: '**',
14 | component: IntelligentPluginLayoutComponent
15 | }
16 | ]
17 | }
18 | ]
19 | }]
20 |
21 | @NgModule({
22 | imports: [RouterModule.forChild(routes)],
23 | exports: [RouterModule]
24 | })
25 | export class IntelligentPluginRoutingModule { }
26 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/intelligent-plugin/intelligent-plugin.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core'
2 |
3 | @Component({
4 | selector: 'eo-ng-intelligent-plugin',
5 | template: `
6 |
7 | `,
8 | styles: [
9 | ]
10 | })
11 | export class IntelligentPluginComponent {
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/intelligent-plugin/layout/layout.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core'
2 | import { EoIntelligentPluginLayoutComponent } from '../../../component/intelligent-plugin/layout/layout.component'
3 | @Component({
4 | selector: 'eo-ng-intelligent-plugin-layout',
5 | templateUrl: '../../../component/intelligent-plugin/layout/layout.component.html',
6 | styles: [
7 | ]
8 | })
9 | export class IntelligentPluginLayoutComponent extends EoIntelligentPluginLayoutComponent {
10 | }
11 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/intelligent-plugin/list/list.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core'
2 | import { EoIntelligentPluginListComponent } from '../../../component/intelligent-plugin/list/list.component'
3 |
4 | @Component({
5 | selector: 'eo-ng-intelligent-plugin-list',
6 | templateUrl: '../../../component/intelligent-plugin/list/list.component.html',
7 | styles: [
8 | ]
9 | })
10 | export class IntelligentPluginListComponent extends EoIntelligentPluginListComponent {}
11 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/intelligent-plugin/publish/publish.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core'
2 | import { EoIntelligentPluginPublishComponent } from '../../../component/intelligent-plugin/publish/publish.component'
3 |
4 | @Component({
5 | selector: 'eo-ng-intelligent-plugin-publish',
6 | templateUrl: '../../../component/intelligent-plugin/publish/publish.component.html',
7 | styles: [
8 | ]
9 | })
10 | export class IntelligentPluginPublishComponent extends EoIntelligentPluginPublishComponent {}
11 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/log-retrieval/conf.ts:
--------------------------------------------------------------------------------
1 |
2 | export const LogRetrievalTableHeadName = [
3 | {
4 | title: ''
5 | },
6 | {
7 | title: ''
8 | },
9 | {
10 | title: ''
11 | }, {
12 | title: '',
13 | width: 98
14 | }
15 | ]
16 |
17 | export const LogRetrievalTableBody = [
18 | {
19 | key: 'file',
20 | left: true,
21 | copy: true
22 | },
23 | {
24 | key: 'size'
25 | },
26 | {
27 | key: 'mod'
28 | },
29 | {
30 | type: 'btn',
31 | right: true,
32 | btns: [{
33 | title: '下载'
34 | }]
35 | }
36 | ]
37 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/log-retrieval/log-retrieval-routing.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core'
2 | import { RouterModule, Routes } from '@angular/router'
3 | import { LogRetrievalComponent } from './log-retrieval.component'
4 |
5 | const routes: Routes = [
6 | {
7 | path: '',
8 | component: LogRetrievalComponent
9 | }
10 | ]
11 |
12 | @NgModule({
13 | imports: [RouterModule.forChild(routes)],
14 | exports: [RouterModule]
15 | })
16 | export class LogRetrievalRoutingModule { }
17 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/log-retrieval/type.ts:
--------------------------------------------------------------------------------
1 |
2 | export type LogFileData = {
3 | file:string
4 | size:string
5 | mod:string
6 | key:string
7 | }
8 |
9 | export type LogOutputData = {
10 | name:string
11 | tail:string
12 | files:Array
13 | active?:boolean // 折叠面板
14 | }
15 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/login/logo/logo.component.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/login/logo/logo.component.scss:
--------------------------------------------------------------------------------
1 | eo-logo:host {
2 | img {
3 | width: 92px;
4 | }
5 | cursor: pointer;
6 | }
7 |
8 | ::selection {
9 | background: var(--find-password);
10 | }
11 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/login/logo/logo.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input } from '@angular/core'
2 |
3 | type LogoType = 'light' | 'dark'
4 |
5 | @Component({
6 | selector: 'eo-ng-apinto-logo',
7 | templateUrl: './logo.component.html',
8 | styleUrls: ['./logo.component.scss']
9 | })
10 | export class LogoComponent {
11 | @Input() type: LogoType = 'light'
12 | }
13 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/login/password/password.component.scss:
--------------------------------------------------------------------------------
1 | form {
2 | width: 350px;
3 | padding: 28px 0 8px 0;
4 | }
5 |
6 | html {
7 | --antd-wave-shadow-color: var(--primary-color) !important;
8 | }
9 |
10 | .ant-input:hover {
11 | border-color: var(--primary-color);
12 | }
13 |
14 | .ant-input:focus,
15 | .ant-input-focused {
16 | border-color: var(--primary-color);
17 | box-shadow: 0 0 0 2px rgb(var(--primary-color), 20%);
18 | }
19 |
20 | button.ant-btn.ant-btn-primary,
21 | button.ant-btn.ant-btn-primary:hover,
22 | button.ant-btn.ant-btn-primary:focus {
23 | height: 40px;
24 | margin-top: 20px;
25 | }
26 |
27 | ::selection {
28 | background: var(--primary-color);
29 | }
30 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/not-found-page/not-found-page.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core'
2 | import { Router } from '@angular/router'
3 | import { EoNgNavigationService } from '../../service/eo-ng-navigation.service'
4 |
5 | @Component({
6 | selector: 'eo-ng-not-found-page',
7 | template: '',
8 | styles: [
9 | ]
10 | })
11 | export class NotFoundPageComponent {
12 | constructor (private router:Router, private navigation:EoNgNavigationService) {
13 | this.router.navigate([this.navigation.getPageRoute()])
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/plugin/plugin-management.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core'
2 | import { Router } from '@angular/router'
3 |
4 | @Component({
5 | selector: 'eo-ng-plugin-management',
6 | template: `
7 | `,
8 | styles: [
9 | ]
10 | })
11 | export class PluginManagementComponent {
12 | constructor (private router:Router) {
13 | if (this.router.url.split('?')[0] === '/module-plugin') {
14 | this.router.navigate(['/', 'module-plugin', 'group', 'list'])
15 | }
16 | }
17 |
18 | ngDoCheck () {
19 | if (this.router.url.split('?')[0] === '/module-plugin') {
20 | this.router.navigate(['/', 'module-plugin', 'group', 'list'])
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/plugin/types/conf.ts:
--------------------------------------------------------------------------------
1 | import { THEAD_TYPE } from 'eo-ng-table'
2 | import { EO_TBODY_TYPE } from 'projects/eo-ng-apinto-table/src/public-api'
3 |
4 | export const PluginListStatusItems = [
5 | { label: '全部', value: '' },
6 | { label: '已启用', value: true },
7 | { label: '未启用', value: false }
8 | ]
9 |
10 | export const PluginInstallConfigTableHeadName:THEAD_TYPE[] = [
11 | { title: '参数名' },
12 | { title: '参数值' },
13 | { title: '描述' }
14 | ]
15 |
16 | export const PluginInstallConfigTableBody: EO_TBODY_TYPE[] = [
17 | {
18 | key: 'name'
19 | },
20 | {
21 | key: 'value',
22 | type: 'input',
23 | placeholderKey: 'placeholder'
24 | },
25 | { key: 'desc' }
26 | ]
27 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/serv-governance/cache/cache.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core'
2 | import { Router } from '@angular/router'
3 |
4 | @Component({
5 | selector: 'eo-ng-cache',
6 | template: `
7 |
8 | `,
9 | styles: [
10 | ]
11 | })
12 | export class CacheComponent {
13 | constructor (private router:Router) {
14 | if (this.router.url.split('?')[0] === '/serv-governance/cache') {
15 | this.router.navigate(['/', 'serv-governance', 'cache', 'group'])
16 | }
17 | }
18 |
19 | ngDoCheck () {
20 | if (this.router.url.split('?')[0] === '/serv-governance/cache') {
21 | this.router.navigate(['/', 'serv-governance', 'cache', 'group'])
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/serv-governance/filter/footer/footer.component.html:
--------------------------------------------------------------------------------
1 |
10 |
13 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/serv-governance/fuse/fuse.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core'
2 | import { Router } from '@angular/router'
3 |
4 | @Component({
5 | selector: 'eo-ng-fuse',
6 | template: `
7 |
8 | `,
9 | styles: [
10 | ]
11 | })
12 | export class FuseComponent {
13 | constructor (private router:Router) {
14 | if (this.router.url === '/serv-governance/fuse') {
15 | this.router.navigate(['/', 'serv-governance', 'fuse', 'group'])
16 | }
17 | }
18 |
19 | ngDoCheck () {
20 | if (this.router.url === '/serv-governance/fuse') {
21 | this.router.navigate(['/', 'serv-governance', 'fuse', 'group'])
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/serv-governance/grey/grey.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core'
2 | import { Router } from '@angular/router'
3 |
4 | @Component({
5 | selector: 'eo-ng-grey',
6 | template: `
7 |
8 | `,
9 | styles: [
10 | ]
11 | })
12 | export class GreyComponent {
13 | constructor (private router:Router) {
14 | if (this.router.url === '/serv-governance/grey') {
15 | this.router.navigate(['/', 'serv-governance', 'grey', 'group'])
16 | }
17 | }
18 |
19 | ngDoCheck () {
20 | if (this.router.url === '/serv-governance/grey') {
21 | this.router.navigate(['/', 'serv-governance', 'grey', 'group'])
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/serv-governance/traffic/message/message.component.html:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/serv-governance/traffic/traffic.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core'
2 | import { Router } from '@angular/router'
3 |
4 | @Component({
5 | selector: 'eo-ng-traffic',
6 | template: `
7 |
8 | `,
9 | styles: [
10 | ]
11 | })
12 | export class TrafficComponent {
13 | constructor (private router:Router) {
14 | if (this.router.url === '/serv-governance/traffic') {
15 | this.router.navigate(['/', 'serv-governance', 'traffic', 'group'])
16 | }
17 | }
18 |
19 | ngDoCheck () {
20 | if (this.router.url === '/serv-governance/traffic') {
21 | this.router.navigate(['/', 'serv-governance', 'traffic', 'group'])
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/serv-governance/visit/visit.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core'
2 | import { Router } from '@angular/router'
3 |
4 | @Component({
5 | selector: 'eo-ng-visit',
6 | template: `
7 |
8 | `,
9 | styles: [
10 | ]
11 | })
12 | export class VisitComponent {
13 | constructor (private router:Router) {
14 | if (this.router.url === '/serv-governance/visit') {
15 | this.router.navigate(['/', 'serv-governance', 'visit', 'group'])
16 | }
17 | }
18 |
19 | ngDoCheck () {
20 | if (this.router.url === '/serv-governance/visit') {
21 | this.router.navigate(['/', 'serv-governance', 'visit', 'group'])
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/system/email/system-email.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core'
2 |
3 | @Component({
4 | selector: 'eo-ng-system-email',
5 | template: `
6 | `,
7 | styles: [
8 | ]
9 | })
10 | export class SystemEmailComponent {
11 | }
12 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/system/external-app/external-app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core'
2 |
3 | @Component({
4 | selector: 'eo-ng-external-app',
5 | template: `
6 | `,
7 | styles: [
8 | ]
9 | })
10 | export class ExternalAppComponent {
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/system/system.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core'
2 |
3 | @Component({
4 | selector: 'eo-ng-system',
5 | template: `
6 | `,
7 | styles: [
8 | `
9 | :host ::ng-deep{
10 | td {
11 | eo-ng-select.ant-select,
12 | eo-ng-select-top-control.ant-select-selector {
13 | width: 100% !important;
14 | }
15 | }
16 | }`
17 | ]
18 | })
19 | export class SystemComponent {
20 | }
21 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/layout/system/webhook/webhook.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core'
2 |
3 | @Component({
4 | selector: 'eo-ng-system-webhook',
5 | template: `
6 |
7 | `,
8 | styles: [
9 | ]
10 | })
11 | export class SystemWebhookComponent {
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/pipe/change-word-color.pipe.ts:
--------------------------------------------------------------------------------
1 | import { Pipe, PipeTransform } from '@angular/core'
2 |
3 | @Pipe({
4 | name: 'changeWordColor'
5 | })
6 | export class ChangeWordColorPipe implements PipeTransform {
7 | // value:需转换的字符串,args[0]:需改变颜色的字符串,args[1]:改变后的颜色
8 | transform (value: string, ...args:Array): unknown {
9 | const wordArray:Array = value.split(args[0])
10 | return wordArray.join(`${args[0]}`)
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/service/crypto.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core'
2 | import * as CryptoJS from 'crypto-js'
3 |
4 | @Injectable({
5 | providedIn: 'root'
6 | })
7 | export class CryptoService {
8 | private key:string = '1e42=7838a1vfc6n'
9 |
10 | // AES加密,登录、修改密码用, 向量默认 1e42=7838a1vfc6n, inputKey是用户名,inputData是密码
11 | encryptByEnAES (inputKey:string, inputData:string, inputIv?:string):string {
12 | const tmpIv = CryptoJS.enc.Latin1.parse(inputIv || this.key)
13 | const tmpKey = CryptoJS.enc.Latin1.parse(CryptoJS.MD5(inputKey).toString() || '')
14 | return CryptoJS.enc.Base64.stringify(CryptoJS.AES.encrypt(inputData, tmpKey, {
15 | iv: tmpIv,
16 | mode: CryptoJS.mode.CBC,
17 | padding: CryptoJS.pad.Pkcs7
18 | }).ciphertext)
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/app/service/http-interceptors/index.ts:
--------------------------------------------------------------------------------
1 | import { HTTP_INTERCEPTORS } from '@angular/common/http'
2 | import { ErrorInterceptor } from './error.interceptor'
3 |
4 | /** Http interceptor providers in outside-in order */
5 | export const httpInterceptorProviders = [
6 | { provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true }
7 | ]
8 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/frontend/projects/core/src/assets/.gitkeep
--------------------------------------------------------------------------------
/frontend/projects/core/src/assets/default-guide-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/frontend/projects/core/src/assets/default-guide-icon.png
--------------------------------------------------------------------------------
/frontend/projects/core/src/assets/default-navigation-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/frontend/projects/core/src/assets/default-navigation-icon.png
--------------------------------------------------------------------------------
/frontend/projects/core/src/assets/default-plugin-icon.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/assets/favicon-pro.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/frontend/projects/core/src/assets/favicon-pro.ico
--------------------------------------------------------------------------------
/frontend/projects/core/src/assets/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/frontend/projects/core/src/assets/favicon.ico
--------------------------------------------------------------------------------
/frontend/projects/core/src/assets/guide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/frontend/projects/core/src/assets/guide.jpg
--------------------------------------------------------------------------------
/frontend/projects/core/src/assets/logo/logo_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/frontend/projects/core/src/assets/logo/logo_dark.png
--------------------------------------------------------------------------------
/frontend/projects/core/src/assets/logo/logo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/frontend/projects/core/src/assets/logo/logo_light.png
--------------------------------------------------------------------------------
/frontend/projects/core/src/assets/side_bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/frontend/projects/core/src/assets/side_bg.jpg
--------------------------------------------------------------------------------
/frontend/projects/core/src/assets/theme/dark.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors": {
3 | "primary": "#7371fc",
4 | "text": "rgba(243, 243, 243, 0.9)",
5 | "inputIcon": "#fff",
6 | "textSecondary": "#ccc",
7 | "border": "rgba(255, 255, 255, 0.1)",
8 | "background": "#212121",
9 | "barBackground": "#212121",
10 | "disabledText": "#666",
11 | "disabledBackground": "#282828",
12 | "textLink": "#1890ff",
13 | "textLinkHover": "#40a9ff",
14 | "textLinkActive": "#096dd9",
15 | "divider": "rgba(255, 255, 255, 0.1)",
16 | "alertDefaultBackground": "rgba(149,149,149,.1)",
17 | "scrollbarTrackBackground": "#212121",
18 | "scrollbarThumbBackground": "rgba(255, 255, 255, 0.2)",
19 | "popoverBackground": "#fff",
20 | "popoverText": "#333",
21 | "tableRowHoverBackground": "#555555"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/assets/theme/light.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors": {
3 | "primary": "#7371fc",
4 | "text": "#333",
5 | "textSecondary": "#999",
6 | "inputIcon": "rgba(0, 0, 0, 0.25)",
7 | "border": "rgba(0, 0, 0, 0.07)",
8 | "background": "#fff",
9 | "barBackground": "#fafafa",
10 | "disabledText": "#bbbbbb",
11 | "disabledBackground": "#f6f6f6",
12 | "textLink": "#1890ff",
13 | "textLinkHover": "#40a9ff",
14 | "textLinkActive": "#096dd9",
15 | "divider": "rgba(0,0,0,.06)",
16 | "alertDefaultBackground": "rgba(149,149,149,.1)",
17 | "scrollbarTrackBackground": "rgba(255, 255, 255, 0.05)",
18 | "scrollbarThumbBackground": "rgba(0, 0, 0, 0.2)",
19 | "popoverText": "#fff",
20 | "popoverBackground": "rgba(0,0,0,.75)",
21 | "layoutSidebarText": "#333"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/environments/basic.ts:
--------------------------------------------------------------------------------
1 | export const defaultEnvironment = {
2 | }
3 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/environments/environment.business.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true,
3 | urlPrefix: '/',
4 | isBusiness: true
5 | }
6 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/environments/environment.business.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: false,
3 | isBusiness: true,
4 | urlPrefix:
5 | '/'
6 | // 'https://mockapi.eolink.com/K25EPjsf31dac8880a551fe2672247d21218bf854cbcf60/'
7 | // 'http://uat.apikit.com:11204/mockApi/Pn83XY3f27fddad8ba775d3bec6b2b0998168ad3db5ccbb/'
8 | }
9 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true,
3 | urlPrefix: '/',
4 | isBusiness: false
5 | }
6 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: false,
3 | isBusiness: false,
4 | urlPrefix:
5 | '/'
6 | // 'https://mockapi.eolink.com/K25EPjsf31dac8880a551fe2672247d21218bf854cbcf60/'
7 | // 'http://uat.apikit.com:11204/mockApi/Pn83XY3f27fddad8ba775d3bec6b2b0998168ad3db5ccbb/'
8 | }
9 |
10 | /*
11 | * For easier debugging in development mode, you can import the following file
12 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
13 | *
14 | * This import should be commented out in production mode because it will have a negative impact
15 | * on performance if an error is thrown.
16 | */
17 | // import 'zone.js/plugins/zone-error'; // Included with Angular CLI.
18 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/frontend/projects/core/src/favicon.ico
--------------------------------------------------------------------------------
/frontend/projects/core/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Apinto
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/input.style.scss:
--------------------------------------------------------------------------------
1 | input[type='file'] {
2 | display: none !important;
3 | }
4 |
5 | textarea.ant-input {
6 | min-height: 68px;
7 | height: 68px;
8 | }
9 |
10 | input[type='number']::-webkit-inner-spin-button,
11 | input[type='number']::-webkit-outer-spin-button {
12 | -webkit-appearance: none;
13 | margin: 0;
14 | }
15 | input[type='number'] {
16 | -moz-appearance: textfield;
17 | }
18 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/main.ts:
--------------------------------------------------------------------------------
1 | import { enableProdMode } from '@angular/core'
2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'
3 |
4 | import { AppModule } from './app/app.module'
5 | import { environment } from './environments/environment'
6 |
7 | if (environment.production) {
8 | enableProdMode()
9 | }
10 |
11 | platformBrowserDynamic().bootstrapModule(AppModule)
12 | .catch(err => console.error(err))
13 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/select.style.scss:
--------------------------------------------------------------------------------
1 | // 表格自带分页的选择器宽度
2 | .ant-pagination-options {
3 | .ant-select,
4 | nz-select-top-control.ant-select-selector {
5 | width: auto !important;
6 | }
7 | }
8 | // select光标与placeholder位置,待组件库修改
9 | .ant-select-multiple .ant-select-selection-search {
10 | margin-inline-start: 2px;
11 | }
12 |
13 | eo-ng-select:not(.ant-select-open)
14 | eo-ng-select-top-control
15 | nz-select-search.ant-select-selection-search {
16 | width: 1px !important;
17 | }
18 |
19 | .ant-select-item {
20 | label[eo-ng-checkbox] {
21 | padding-top: 0px;
22 | }
23 | }
24 |
25 | .ant-select-selection-placeholder {
26 | color: var(--input-placeholder-color) !important;
27 | }
28 |
--------------------------------------------------------------------------------
/frontend/projects/core/src/variables.css:
--------------------------------------------------------------------------------
1 | /* UI component */
2 | :root {
3 | --icon-size: 14px;
4 | --border-radius: 4px;
5 |
6 | --layout-header-height: 50px;
7 | --layout-footer-height: 30px;
8 |
9 | --btn-icon-margin: 5px;
10 | --button-height: 32px;
11 | --tabs-height: 43px;
12 | --tree-item-height: 30px;
13 | --collapse-header-height: 46px;
14 |
15 | --table-font-size: 14px;
16 | --table-row-height: 40px;
17 | --table-item-padding: 4px;
18 |
19 | --padding-x: 20px;
20 | --padding-y: 15px;
21 | --padding: var(--padding-y) var(--padding-x);
22 | --margin: 20px;
23 | }
24 | /* System customer */
25 | :root {
26 | --layout-sidebar-width: 90px;
27 | --layout-sidebar-item-height: auto;
28 | --edit-inside-bar-height: 53px;
29 | }
30 |
--------------------------------------------------------------------------------
/frontend/projects/eo-ng-apinto-table/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3 | "dest": "../../dist/eo-ng-apinto-table",
4 | "lib": {
5 | "entryFile": "src/public-api.ts"
6 | }
7 | }
--------------------------------------------------------------------------------
/frontend/projects/eo-ng-apinto-table/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "eo-ng-apinto-table",
3 | "version": "0.0.1",
4 | "peerDependencies": {
5 | "@angular/common": "^14.0.0",
6 | "@angular/core": "^14.0.0"
7 | },
8 | "dependencies": {
9 | "tslib": "^2.3.0"
10 | }
11 | }
--------------------------------------------------------------------------------
/frontend/projects/eo-ng-apinto-table/src/lib/types.ts:
--------------------------------------------------------------------------------
1 | import { TemplateRef } from '@angular/core'
2 | import { TBODY_TYPE, THEAD_TYPE } from 'eo-ng-table'
3 |
4 | export interface EO_TBODY_TYPE extends TBODY_TYPE{
5 | check?:Function
6 | tooltip?:string | TemplateRef
7 | json?:boolean
8 | copy?:boolean
9 | }
10 |
11 | export interface EO_THEAD_TYPE extends THEAD_TYPE{
12 | required?:boolean
13 | titleString?:string // require用
14 | tooltip?:string
15 | }
16 |
--------------------------------------------------------------------------------
/frontend/projects/eo-ng-apinto-table/src/public-api.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Public API Surface of eo-ng-apinto-table
3 | */
4 |
5 | export * from './lib/eo-ng-apinto-table.module'
6 | export * from './lib/table/table.component'
7 | export * from './lib/types'
8 |
--------------------------------------------------------------------------------
/frontend/projects/eo-ng-apinto-table/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "outDir": "../../dist/eo-ng-apinto-table/tsc-bundle",
5 | "module": "umd",
6 | "moduleResolution": "node",
7 | "sourceMap": true,
8 | "emitDecoratorMetadata": true,
9 | "experimentalDecorators": true,
10 | "lib": ["es2015", "dom"],
11 | "noImplicitAny": true,
12 | "suppressImplicitAnyIndexErrors": true,
13 | "skipLibCheck": true,
14 | "allowSyntheticDefaultImports": true
15 | },
16 | "exclude": [
17 | "./**/*.test.ts",
18 | "./**/test.ts",
19 | "./**/*.spec.ts",
20 | "./**/*.test.js",
21 | "./**/*.spec.js"
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/frontend/projects/eo-ng-apinto-table/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "../../tsconfig.json",
4 | "compilerOptions": {
5 | "outDir": "../../out-tsc/lib",
6 | "declaration": true,
7 | "declarationMap": true,
8 | "inlineSources": true,
9 | "types": []
10 | },
11 | "exclude": [
12 | "src/test.ts",
13 | "**/*.spec.ts"
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/frontend/projects/eo-ng-apinto-table/tsconfig.lib.prod.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "./tsconfig.lib.json",
4 | "compilerOptions": {
5 | "declarationMap": false
6 | },
7 | "angularCompilerOptions": {
8 | "compilationMode": "partial"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/frontend/projects/eo-ng-apinto-table/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "../../tsconfig.json",
4 | "compilerOptions": {
5 | "outDir": "../../out-tsc/spec",
6 | "types": [
7 | "jasmine"
8 | ]
9 | },
10 | "files": [
11 | "src/test.ts"
12 | ],
13 | "include": [
14 | "**/*.spec.ts",
15 | "**/*.d.ts"
16 | ]
17 | }
18 |
--------------------------------------------------------------------------------
/frontend/proxy.config.demo.json:
--------------------------------------------------------------------------------
1 | {
2 | "/api": {
3 | "target": "https://demo-dashboard.apinto.com/",
4 | "changeOrigin": true
5 | },
6 | "/_system": {
7 | "target": "https://demo-dashboard.apinto.com/",
8 | "changeOrigin": true
9 | },
10 | "/sso": {
11 | "target": "https://demo-dashboard.apinto.com/",
12 | "changeOrigin": true
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/frontend/test/setup-jest.ts:
--------------------------------------------------------------------------------
1 | import 'jest-preset-angular/setup-jest'
2 |
--------------------------------------------------------------------------------
/frontend/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "./tsconfig.json",
4 | "compilerOptions": {
5 | "outDir": "./out-tsc/app",
6 | "types": ["node"]
7 | },
8 | "files": [
9 | "projects/core/src/main.ts",
10 | "projects/core/src/polyfills.ts"
11 | ],
12 | "include": [
13 | "src/**/*.d.ts"
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/frontend/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "esModuleInterop": true,
4 | "outDir": "./out-tsc/spec",
5 | "types": ["jest", "node"],
6 | "target": "es6",
7 | "module": "umd",
8 | "moduleResolution": "node",
9 | "sourceMap": true,
10 | "emitDecoratorMetadata": true,
11 | "experimentalDecorators": true,
12 | "lib": ["es2015", "es2016", "es2019", "dom"],
13 | "noImplicitAny": true,
14 | "suppressImplicitAnyIndexErrors": true,
15 | "skipLibCheck": true,
16 | "allowSyntheticDefaultImports": true,
17 | "baseUrl": "./"
18 | },
19 | "include": ["src/**/*.spec.ts", "src/**/*.d.ts"]
20 | }
21 |
--------------------------------------------------------------------------------
/grpc-service/notice_send.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | option go_package = "github.com/eolinker/apinto-monitor/grpc-service";
4 |
5 | message NoticeSendResp {
6 | int32 send_status = 1;
7 | string err_msg = 2;
8 | }
9 |
10 | message NoticeMsg {
11 | string title = 1;
12 | string msg = 2;
13 | }
14 |
15 | message NoticeSendReq {
16 | repeated string user_names = 1;
17 | int32 namespace_id = 2;
18 | map notices = 3;
19 | }
20 |
21 | service NoticeSend {
22 | rpc Send(NoticeSendReq) returns (NoticeSendResp) {}
23 | }
24 |
--------------------------------------------------------------------------------
/initialize/inner-plugin-manager/embed_plugin.go:
--------------------------------------------------------------------------------
1 | package inner_plugin_manager
2 |
3 | var _ IInnerPlugin = (*embedPlugin)(nil)
4 |
5 | type embedPlugin struct {
6 | //TODO 存FS?
7 | }
8 |
9 | func (e embedPlugin) GetDefine() interface{} {
10 | //TODO implement me
11 | panic("implement me")
12 | }
13 |
14 | func (e embedPlugin) GetIcon(fileName string) ([]byte, error) {
15 | //TODO implement me
16 | panic("implement me")
17 | }
18 |
19 | func (e embedPlugin) GetReadme(fileName string) ([]byte, error) {
20 | //TODO implement me
21 | panic("implement me")
22 | }
23 |
24 | func (e embedPlugin) GetResourcesFile(filePath string) ([]byte, error) {
25 | //TODO implement me
26 | panic("implement me")
27 | }
28 |
--------------------------------------------------------------------------------
/initialize/inner-plugin-manager/export.go:
--------------------------------------------------------------------------------
1 | package inner_plugin_manager
2 |
3 | import "embed"
4 |
5 | // RegisterInnerPluginFromEmbed 保存来源为内嵌目录的内置插件
6 | func RegisterInnerPluginFromEmbed(pluginID string, source embed.FS) error {
7 | //TODO 从来源解析出实现了IInnerPlugin的资源
8 |
9 | _innerPluginManager.setInnerPlugin(pluginID, &embedPlugin{})
10 | return nil
11 | }
12 |
13 | func EnablePlugin(pluginID string) error {
14 | return _innerPluginManager.enableInnerPlugin(pluginID)
15 | }
16 |
17 | func GetInnerPlugin(pluginID string) (IInnerPlugin, bool) {
18 | return _innerPluginManager.getInnerPlugin(pluginID)
19 | }
20 |
--------------------------------------------------------------------------------
/initialize/inner-plugin-manager/interface.go:
--------------------------------------------------------------------------------
1 | package inner_plugin_manager
2 |
3 | type IInnerPlugin interface {
4 | GetDefine() interface{}
5 | GetIcon(fileName string) ([]byte, error)
6 | GetReadme(fileName string) ([]byte, error)
7 | GetResourcesFile(filePath string) ([]byte, error)
8 | }
9 |
--------------------------------------------------------------------------------
/initialize/plugin-group/plugin_group.yml:
--------------------------------------------------------------------------------
1 | - id: "core_module"
2 | name: "核心模块"
3 | - id: "strategy"
4 | name: "策略"
5 | - id: "access_auth"
6 | name: "访问鉴权"
7 | - id: "security"
8 | name: "安全"
9 | - id: "data"
10 | name: "数据处理"
11 | - id: "log"
12 | name: "日志"
13 | - id: "devops"
14 | name: "DevOps"
15 |
--------------------------------------------------------------------------------
/initialize/plugin_group.go:
--------------------------------------------------------------------------------
1 | package initialize
2 |
3 | import (
4 | _ "embed"
5 |
6 | "gopkg.in/yaml.v3"
7 | )
8 |
9 | var (
10 | //go:embed plugin_group.yml
11 | pluginGroupsContent []byte
12 |
13 | groupList []*PluginGroupsItem
14 | )
15 |
16 | type PluginGroupsItem struct {
17 | ID string `json:"id" yaml:"id"`
18 | Name string `json:"name" yaml:"name"`
19 | }
20 |
21 | func init() {
22 | // 初始化插件分组列表
23 | groupList = make([]*PluginGroupsItem, 0)
24 | err := yaml.Unmarshal(pluginGroupsContent, &groupList)
25 | if err != nil {
26 | panic(err)
27 | }
28 | }
29 |
30 | func GetModulePluginGroups() []*PluginGroupsItem {
31 | return groupList
32 | }
33 |
--------------------------------------------------------------------------------
/initialize/plugin_group.yml:
--------------------------------------------------------------------------------
1 | - id: "core_module"
2 | name: "核心模块"
3 | - id: "strategy"
4 | name: "策略"
5 | - id: "access_auth"
6 | name: "访问鉴权"
7 | - id: "security"
8 | name: "安全"
9 | - id: "log"
10 | name: "日志"
11 | - id: "devops"
12 | name: "DevOps"
--------------------------------------------------------------------------------
/initialize/plugins/embed/api.apinto.com/README.md:
--------------------------------------------------------------------------------
1 | ## 基本介绍
2 | 管理和配置API转发信息,支持配置多协议接口,包括HTTP/HTTPS、Webservice、Restful、SOAP等多种请求协议,支持从Apikit、Postcat、Swagger等API管理工具中一键同步API。
3 | ## 功能特性
4 | - 管理和配置API转发信息,包括:API请求路径、上游服务、请求协议、请求方法、超时时间、重试次数等。
5 | - 一键同步Apikit、Postcat、Swagger等API管理工具中的API。
6 | - 一键发布API到集群节点,供客户端调用。
7 | - 支持HTTP/HTTPS、Webservice、Restful、SOAP等多种请求协议。
8 |
9 | ## 更新日志
10 | ### V1.0(2023-4-30)
11 | - 插件上线
--------------------------------------------------------------------------------
/initialize/plugins/embed/api.apinto.com/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/initialize/plugins/embed/api.apinto.com/logo.png
--------------------------------------------------------------------------------
/initialize/plugins/embed/api.apinto.com/plugin.yml:
--------------------------------------------------------------------------------
1 | id: "api.apinto.com"
2 | name: "api"
3 | cname: "API管理"
4 | resume: "管理和配置API转发信息,支持配置多协议接口,包括HTTP/HTTPS、Webservice、Restful、SOAP等多种请求协议。"
5 | version: "v1.0.7"
6 | icon: "logo.png"
7 | driver: "api.apinto.com"
8 | type: 1 #0为框架模块 1为核心模块 2为内置模块 3为非内置
9 | auto: true
10 | is_can_disable: false
11 | is_can_uninstall: false
12 | visible_in_navigation: true
13 | visible_in_market: true
14 | front: router
15 | navigation: "navigation.api"
16 | group_id: "core_module"
--------------------------------------------------------------------------------
/initialize/plugins/embed/apispace.apinto.com/apispace.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/initialize/plugins/embed/apispace.apinto.com/apispace.jpg
--------------------------------------------------------------------------------
/initialize/plugins/embed/apispace.apinto.com/plugin.yml:
--------------------------------------------------------------------------------
1 | id: "apispace.apinto.com"
2 | name: "apispace"
3 | cname: "APISpace接口商店"
4 | resume: "APISpace是Eolink旗下专业的API开放与交易平台,为超过100万开发者提供专业的API服务,所有 API均提供免费试用,让您无忧探索广阔的API世界"
5 | version: "v1.0.1"
6 | icon: "apispace.jpg"
7 | driver: "remote"
8 | type: 2 #0为框架模块 1为核心模块 2为内置模块 3为非内置
9 | auto: true
10 | is_can_disable: true
11 | is_can_uninstall: false
12 | visible_in_navigation: true
13 | visible_in_market: true
14 | front:
15 | navigation: "navigation.api_market"
16 | group_id: ""
17 | define:
18 | internet: true
19 | server: "https://www.apispace.com"
20 | path: "/explore/service/?utm_source=apinto"
--------------------------------------------------------------------------------
/initialize/plugins/embed/application.apinto.com/README.md:
--------------------------------------------------------------------------------
1 | ## 基本介绍
2 | 应用是对请求来源的抽象概念,其可以是一个客户端App,也可以是一个后端服务,还可以是Web App......
3 |
4 | 应用管理统一管理应用在各个集群的生命周期。应用作为业务通讯的发起者,贯穿整个调用链。
5 |
6 | 在安全方面,网关可以对应用请求的流量进行鉴权认证和授权访问,保障请求流量安全合规转发到后端服务。
7 |
8 | 在监控方面,网关可以在应用维度监控调用API情况,帮助运维或运营分析应用调用趋势,继而做出相应的策略。
9 |
10 | ## 功能特性
11 | - 支持多种鉴权方式
12 | - 单应用多用户模式
13 | - 支持以应用为单位参与服务治理
14 |
15 | ## 更新日志
16 | ### V1.0(2023-4-30)
17 | - 插件上线
--------------------------------------------------------------------------------
/initialize/plugins/embed/application.apinto.com/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/initialize/plugins/embed/application.apinto.com/logo.png
--------------------------------------------------------------------------------
/initialize/plugins/embed/application.apinto.com/plugin.yml:
--------------------------------------------------------------------------------
1 | id: "application.apinto.com"
2 | name: "app"
3 | cname: "应用管理"
4 | resume: "应用管理统一管理应用在各个集群的生命周期。应用作为业务通讯的发起者,贯穿整个调用链。"
5 | version: "v1.0.7"
6 | icon: "logo.png"
7 | driver: "application.apinto.com"
8 | type: 1 #0为框架模块 1为核心模块 2为内置模块 3为非内置
9 | auto: true
10 | is_can_disable: false
11 | is_can_uninstall: false
12 | visible_in_navigation: true
13 | visible_in_market: true
14 | front:
15 | navigation: "navigation.application"
16 | group_id: "core_module"
--------------------------------------------------------------------------------
/initialize/plugins/embed/audit.apinto.com/README.md:
--------------------------------------------------------------------------------
1 | ## 基本介绍
2 | Debug日志记录使用者在控制台操作的事件,包括创建、编辑、删除、上线、下线等。
3 |
4 | 通过Debug日志,我们可以将操作记录作为证据留痕。当系统存在多个用户操作时,一定会出现纠纷,特别是基于系统开展运营时,用户数据出现操作问题,到底是谁的责任?
5 |
6 | 在错误面前,鲜有人主动承认,此时,日志就有了用武之地,定位到人后,除定责外,还能起到对系统坚定信心的作用。
7 | ## 功能特性
8 | - 提供详细的控制台操作日志信息
9 | - 支持多条件筛选日志,包括操作类型、操作对象、操作时间
10 | - 支持关键字查询用户操作日志信息
11 | ## 更新日志
12 | ### V1.0(2023-4-30)
13 | - 插件上线
--------------------------------------------------------------------------------
/initialize/plugins/embed/audit.apinto.com/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/initialize/plugins/embed/audit.apinto.com/logo.png
--------------------------------------------------------------------------------
/initialize/plugins/embed/audit.apinto.com/plugin.yml:
--------------------------------------------------------------------------------
1 | id: "audit.apinto.com"
2 | name: "audit-log"
3 | cname: "Debug日志"
4 | resume: "Debug日志记录使用者在控制台操作的事件,包括创建、编辑、删除、上线、下线等。"
5 | version: "v1.0.7"
6 | icon: "logo.png"
7 | driver: "audit.apinto.com"
8 | type: 2 #0为框架模块 1为核心模块 2为内置模块 3为非内置
9 | auto: true
10 | is_can_disable: true
11 | is_can_uninstall: false
12 | visible_in_navigation: true
13 | visible_in_market: true
14 | front:
15 | navigation: "navigation.system"
16 | group_id: "log"
--------------------------------------------------------------------------------
/initialize/plugins/embed/cluster.apinto.com/README.md:
--------------------------------------------------------------------------------
1 | ## 基本介绍
2 | 管理和维护多业务、多环境集群,帮助管理同城双活、两地三中心、异地多活等架构场景集群配置,保证集群间信息同步。支持以集群为最小粒度发布服务、上游信息、策略、插件配置、环境变量等相关信息。
3 | ## 功能特性
4 | - 支持同城双活、两地三中心、异地多活架构集群场景配置同步。
5 | - 支持多业务、多环境集群同步。
6 | - 支持以集群为最小粒度发布、下线配置信息。
7 |
8 | ## 更新日志
9 | ### V1.0(2023-4-30)
10 | - 插件上线
--------------------------------------------------------------------------------
/initialize/plugins/embed/cluster.apinto.com/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/initialize/plugins/embed/cluster.apinto.com/logo.png
--------------------------------------------------------------------------------
/initialize/plugins/embed/cluster.apinto.com/plugin.yml:
--------------------------------------------------------------------------------
1 | id: "cluster.apinto.com"
2 | name: "cluster"
3 | cname: "集群"
4 | resume: "管理和维护多业务、多环境集群,帮助管理同城双活、两地三中心、异地多活等架构场景集群配置,保证集群间信息同步。"
5 | version: "v1.0.7"
6 | icon: "logo.png"
7 | driver: "cluster.apinto.com"
8 | type: 1 #0为框架模块 1为核心模块 2为内置模块 3为非内置
9 | auto: true
10 | is_can_disable: false
11 | is_can_uninstall: false
12 | visible_in_navigation: true
13 | visible_in_market: true
14 | front: deploy
15 | navigation: "navigation.infrastructure"
16 | group_id: "core_module"
--------------------------------------------------------------------------------
/initialize/plugins/embed/discovery.apinto.com/README.md:
--------------------------------------------------------------------------------
1 | ## 基本介绍
2 | 服务发现是指使用一个注册中心来记录分布式系统中的全部服务的信息,以便其他服务能够快速的找到这些已注册的服务。
3 |
4 | 服务发现有三个角色,服务提供者、服务消费者和服务中介。
5 | - 服务中介:联系服务提供者和服务消费者的桥梁。
6 | - 服务提供者:将自己提供的服务地址注册到服务中介。
7 | - 服务消费者:从服务中介那里查找自己想要的服务的地址,然后享受这个服务。服务中介提供多个服务,每个服务对应多个服务提供者。
8 |
9 | 当服务提供者的节点发生宕机、离线等原因导致不可正常提供服务时,服务中介会及时获取相关信息,将相关节点信息从记录表中删除,服务消费者将不再请求故障节点。
10 |
11 | 当服务提供者新辑入时,及时通知服务中介,此时,服务消费者就可以从众多节点中选择其一进行消费。
12 | ## 功能特性
13 | - 支持接入Eureka、Consul、Nacos
14 | - 静态服务发现支持健康检查,实时监测节点的连通情况
15 | - 支持引用环境变量
16 | ## 更新日志
17 | ### V1.0(2023-4-30)
18 | - 插件上线
--------------------------------------------------------------------------------
/initialize/plugins/embed/discovery.apinto.com/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/initialize/plugins/embed/discovery.apinto.com/logo.png
--------------------------------------------------------------------------------
/initialize/plugins/embed/email.apinto.com/README.md:
--------------------------------------------------------------------------------
1 | ## 基本介绍
2 | 配置系统邮件服务器信息,系统内邮件(如告警邮件)将会使用该邮件服务器发送。
3 | ## 功能特性
4 | - 使用SMTP协议发送邮件
5 | - 支持SSL/TLS协议
6 | ## 更新日志
7 | ### V1.0(2023-4-30)
8 | - 插件上线
--------------------------------------------------------------------------------
/initialize/plugins/embed/email.apinto.com/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/initialize/plugins/embed/email.apinto.com/logo.png
--------------------------------------------------------------------------------
/initialize/plugins/embed/email.apinto.com/plugin.yml:
--------------------------------------------------------------------------------
1 | id: "email.apinto.com"
2 | name: "email"
3 | cname: "邮箱设置"
4 | resume: "配置系统邮件服务器信息,系统内邮件(如告警邮件)将会使用该邮件服务器发送。"
5 | version: "v1.0.7"
6 | icon: "logo.png"
7 | driver: "email.apinto.com"
8 | type: 2 #0为框架模块 1为核心模块 2为内置模块 3为非内置
9 | auto: true
10 | is_can_disable: true
11 | is_can_uninstall: false
12 | visible_in_navigation: true
13 | visible_in_market: true
14 | front: system
15 | navigation: "navigation.system"
16 | group_id: ""
--------------------------------------------------------------------------------
/initialize/plugins/embed/ext_app.apinto.com/README.md:
--------------------------------------------------------------------------------
1 | ## 基本介绍
2 | OpenAPI 定义 Web API 的标准接口描述和编程语言无关接口描述。 它使人类和计算机可以发现和了解服务的功能,而无需访问源代码、其他文档或检查网络流量。
3 |
4 | 利用该插件的提供的OpenAPI,将内容进行重新搭配,从而制作出独特的、具有新价值的新应用/产品。
5 |
6 | API管理平台Apikit、Postcat已经接入了OpenAPI,只需简单几步配置,从能将Apikit、Postcat中的API信息一键导入到Apinto网关。
7 | ## 功能特性
8 | - 提供OpenAPI供第三方应用/产品集成。
9 | - 配置外部应用,一键同步Apikit、Postcat的API信息到Apinto网关。
10 |
11 | ## 更新日志
12 | ### V1.0(2023-4-30)
13 | - 插件上线
--------------------------------------------------------------------------------
/initialize/plugins/embed/ext_app.apinto.com/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/initialize/plugins/embed/ext_app.apinto.com/logo.png
--------------------------------------------------------------------------------
/initialize/plugins/embed/ext_app.apinto.com/plugin.yml:
--------------------------------------------------------------------------------
1 | id: "ext_app.apinto.com"
2 | name: "ext-app"
3 | cname: "OpenAPI"
4 | resume: "利用该插件的提供的OpenAPI,将内容进行重新搭配,从而制作出独特的、具有新价值的新应用/产品。"
5 | version: "v1.0.1"
6 | icon: "logo.png"
7 | driver: "ext_app.apinto.com"
8 | type: 2 #0为框架模块 1为核心模块 2为内置模块 3为非内置
9 | auto: true
10 | is_can_disable: true
11 | is_can_uninstall: false
12 | visible_in_navigation: true
13 | visible_in_market: true
14 | front: system
15 | navigation: "navigation.system"
16 | group_id: "devops"
--------------------------------------------------------------------------------
/initialize/plugins/embed/log.apinto.com/README.md:
--------------------------------------------------------------------------------
1 | ## 基本介绍
2 | 日志检索提供基本的针对apinto节点的日志检索能力
3 | ## 功能特性
4 | - 针对节点,查询所有文件类型的日志列表
5 | - 支持追踪节点日志、请求Access日志
6 | - 支持在控制台下载日志,无需进入服务器操作
7 | - 按日志对象监视新增日志
8 | ## 功能截图
9 | ### 日志列表
10 |
11 | 
12 |
13 | ### 追踪日志
14 |
15 | 
16 |
17 | ## 版本需求
18 | 需要 apinto版本 0.13 及以上
19 | ## 更新日志
20 | ### V1.0(2023-6-19)
21 | - 插件上线
--------------------------------------------------------------------------------
/initialize/plugins/embed/log.apinto.com/plugin.yml:
--------------------------------------------------------------------------------
1 | id: "log.apinto.com"
2 | name: "log"
3 | cname: "日志检索"
4 | resume: "检索apinto的文件日志,包括节点日志和基于文件驱动的access日志"
5 | version: "v1.0.3"
6 | icon: "日志检索.png"
7 | driver: "log.apinto.com"
8 | type: 2 #0为框架模块 1为核心模块 2为内置模块 3为非内置
9 | auto: true
10 | is_can_disable: true
11 | is_can_uninstall: false
12 | visible_in_navigation: true
13 | visible_in_market: true
14 | front:
15 | navigation: "navigation.system"
16 | group_id: "log"
--------------------------------------------------------------------------------
/initialize/plugins/embed/log.apinto.com/日志检索.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/initialize/plugins/embed/log.apinto.com/日志检索.png
--------------------------------------------------------------------------------
/initialize/plugins/embed/module_plugin.apinto.com/README.md:
--------------------------------------------------------------------------------
1 | # 企业插件
--------------------------------------------------------------------------------
/initialize/plugins/embed/module_plugin.apinto.com/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/initialize/plugins/embed/module_plugin.apinto.com/logo.png
--------------------------------------------------------------------------------
/initialize/plugins/embed/module_plugin.apinto.com/plugin.yml:
--------------------------------------------------------------------------------
1 | id: "module_plugin.apinto.com"
2 | name: "module-plugin"
3 | cname: "插件管理"
4 | resume: ""
5 | version: "v1.0.5"
6 | icon: "logo.png"
7 | driver: "module_plugin.apinto.com"
8 | type: 0 #0为框架模块 1为核心模块 2为内置模块 3为非内置
9 | auto: true
10 | is_can_disable: false
11 | is_can_uninstall: false
12 | visible_in_navigation: true
13 | visible_in_market: false
14 | front:
15 | navigation: "navigation.module_plugin"
16 | group_id: "core_module"
--------------------------------------------------------------------------------
/initialize/plugins/embed/open_api.apinto.com/README.md:
--------------------------------------------------------------------------------
1 | ## 基本介绍
2 | OpenAPI 定义 Web API 的标准接口描述和编程语言无关接口描述。 它使人类和计算机可以发现和了解服务的功能,而无需访问源代码、其他文档或检查网络流量。
3 |
4 | 利用该插件的提供的OpenAPI,将内容进行重新搭配,从而制作出独特的、具有新价值的新应用/产品。
5 |
6 | API管理平台Apikit、Postcat已经接入了OpenAPI,只需简单几步配置,从能将Apikit、Postcat中的API信息一键导入到Apinto网关。
7 | ## 功能特性
8 | - 提供OpenAPI供第三方应用/产品集成。
9 | - 配置外部应用,一键同步Apikit、Postcat的API信息到Apinto网关。
10 |
11 | ## 更新日志
12 | ### V1.0(2023-4-30)
13 | - 插件上线
--------------------------------------------------------------------------------
/initialize/plugins/embed/open_api.apinto.com/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/initialize/plugins/embed/open_api.apinto.com/logo.png
--------------------------------------------------------------------------------
/initialize/plugins/embed/open_api.apinto.com/plugin.yml:
--------------------------------------------------------------------------------
1 | id: "open_api.apinto.com"
2 | name: "open_api"
3 | cname: "open-api"
4 | resume: "利用该插件的提供的OpenAPI,将内容进行重新搭配,从而制作出独特的、具有新价值的新应用/产品。"
5 | version: "v1.0.7"
6 | icon: "logo.png"
7 | driver: "open_api.apinto.com"
8 | type: 0 #0为框架模块 1为核心模块 2为内置模块 3为非内置
9 | auto: true
10 | is_can_disable: false
11 | is_can_uninstall: false
12 | visible_in_navigation: false
13 | visible_in_market: false
14 | front: ""
15 | group_id: "core_module"
--------------------------------------------------------------------------------
/initialize/plugins/embed/plugin.apinto.com/README.md:
--------------------------------------------------------------------------------
1 | # 全局插件
--------------------------------------------------------------------------------
/initialize/plugins/embed/plugin.apinto.com/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/initialize/plugins/embed/plugin.apinto.com/logo.png
--------------------------------------------------------------------------------
/initialize/plugins/embed/plugin.apinto.com/plugin.yml:
--------------------------------------------------------------------------------
1 | id: "plugin.apinto.com"
2 | name: "plugin"
3 | cname: "节点插件"
4 | resume: ""
5 | version: "v1.0.3"
6 | icon: "logo.png"
7 | driver: "plugin.apinto.com"
8 | type: 0 #0为框架模块 1为核心模块 2为内置模块 3为非内置
9 | auto: true
10 | is_can_disable: false
11 | is_can_uninstall: false
12 | visible_in_navigation: true
13 | visible_in_market: false
14 | front: deploy
15 | navigation: "navigation.infrastructure"
16 | group_id: "core_module"
--------------------------------------------------------------------------------
/initialize/plugins/embed/plugin_template.apinto.com/README.md:
--------------------------------------------------------------------------------
1 | # 插件模板
--------------------------------------------------------------------------------
/initialize/plugins/embed/plugin_template.apinto.com/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/initialize/plugins/embed/plugin_template.apinto.com/logo.png
--------------------------------------------------------------------------------
/initialize/plugins/embed/plugin_template.apinto.com/plugin.yml:
--------------------------------------------------------------------------------
1 | id: "plugin_template.apinto.com"
2 | name: "plugin-template"
3 | cname: "API操作模板"
4 | resume: ""
5 | version: "v1.0.4"
6 | icon: "logo.png"
7 | driver: "plugin_template.apinto.com"
8 | type: 0 #0为框架模块 1为核心模块 2为内置模块 3为非内置
9 | auto: true
10 | is_can_disable: false
11 | is_can_uninstall: false
12 | visible_in_navigation: true
13 | visible_in_market: false
14 | front: router
15 | navigation: "navigation.public_config"
16 | group_id: "core_module"
--------------------------------------------------------------------------------
/initialize/plugins/embed/strategy-cache.apinto.com/README.md:
--------------------------------------------------------------------------------
1 | ## 基本介绍
2 | 缓存是一种本地保存远端资源的机制,不管是在客户端、还是在服务端存储着,用相同的URL进行数据请求,可以直接从缓存中请求资源而不再访问源服务器。
3 |
4 | 数据缓存大致可以分为:数据库缓存、服务器端缓存(代理服务器缓存、CDN缓存)、浏览器缓存。
5 |
6 | 其意义主要在:
7 | - 避免了冗余的数据传输,节省流量;
8 | - 加快了用户访问网页的速度;
9 | - 减小了服务器的压力。
10 |
11 | Apinto网关数据缓存本质属于代理服务器缓存,通过缓存上游服务的静态资源,如:图片、静态页面等资源,减少于上游服务器的交互,加快接口/页面访问速度,减小服务器的压力。
12 |
13 | ## 功能特性
14 | - 多维度筛选请求流量,用户可根据请求流量中属性:应用、IP、API、上游、请求路径、请求方式等组合条件精准筛选流量。
15 | - 支持针对应用或IP获取缓存的响应数据。
16 | - 支持缓存有效时间设置。
17 |
18 | ## 更新日志
19 | ### V1.0(2023-4-30)
20 | - 插件上线
--------------------------------------------------------------------------------
/initialize/plugins/embed/strategy-cache.apinto.com/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/initialize/plugins/embed/strategy-cache.apinto.com/logo.png
--------------------------------------------------------------------------------
/initialize/plugins/embed/strategy-cache.apinto.com/plugin.yml:
--------------------------------------------------------------------------------
1 | id: "strategy-cache.apinto.com"
2 | name: "cache"
3 | cname: "数据缓存"
4 | resume: "通过缓存上游服务的静态资源,如:图片、静态页面等资源,减少于上游服务器的交互,加快接口/页面访问速度,减小服务器的压力。"
5 | version: "v1.0.7"
6 | icon: "logo.png"
7 | driver: "strategy-cache.apinto.com"
8 | type: 2 #0为框架模块 1为核心模块 2为内置模块 3为非内置
9 | auto: true
10 | is_can_disable: true
11 | is_can_uninstall: false
12 | visible_in_navigation: true
13 | visible_in_market: true
14 | front: serv-governance
15 | navigation: "navigation.strategy"
16 | group_id: "strategy"
--------------------------------------------------------------------------------
/initialize/plugins/embed/strategy-fuse.apinto.com/README.md:
--------------------------------------------------------------------------------
1 | ## 基本介绍
2 | 简单来说,用API的“出错比例”来表示这个API的健康状态,当这个比例值高于设定的阈值,API自动抛出异常,终止服务,这个过程就叫做自动熔断。
3 |
4 | API熔断后,可以保护数据库、上游服务等基础服务不受不健康的API的影响,减轻基础服务的压力,提高响应速度。
5 | ## 功能特性
6 | - 多维度筛选请求流量,用户可根据请求流量中属性:应用、IP、API、上游、请求路径、请求方式等组合条件精准筛选流量。
7 | - 支持熔断上游或上游的API。
8 | - 支持熔断自动恢复健康机制。
9 | - 对于正处于熔断期并符合筛选条件的请求流量,支持自定义响应内容。
10 | ## 更新日志
11 | ### V1.0(2023-4-30)
12 | - 插件上线
--------------------------------------------------------------------------------
/initialize/plugins/embed/strategy-fuse.apinto.com/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/initialize/plugins/embed/strategy-fuse.apinto.com/logo.png
--------------------------------------------------------------------------------
/initialize/plugins/embed/strategy-fuse.apinto.com/plugin.yml:
--------------------------------------------------------------------------------
1 | id: "strategy-fuse.apinto.com"
2 | name: "fuse"
3 | cname: "熔断"
4 | resume: 用API的"出错比例"来表示这个API的健康状态,,当这个比例值高于设定的阈值,API自动抛出异常,终止服务。
5 | version: "v1.0.7"
6 | icon: "logo.png"
7 | driver: "strategy-fuse.apinto.com"
8 | type: 2 #0为框架模块 1为核心模块 2为内置模块 3为非内置
9 | auto: true
10 | is_can_disable: true
11 | is_can_uninstall: false
12 | visible_in_navigation: true
13 | visible_in_market: true
14 | front: serv-governance
15 | navigation: "navigation.strategy"
16 | group_id: "strategy"
--------------------------------------------------------------------------------
/initialize/plugins/embed/strategy-grey.apinto.com/README.md:
--------------------------------------------------------------------------------
1 | ## 基本介绍
2 | 灰度发布(又名金丝雀发布)是指在黑与白之间,能够平滑过渡的一种发布方式。
3 |
4 | 在其上可以进行A/B testing,即让一部分用户继续用产品特性A,一部分用户开始用产品特性B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面来。
5 |
6 | 灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度。
7 |
8 | ## 功能特性
9 | - 多维度筛选请求流量,用户可根据请求流量中属性:应用、IP、API、上游、请求路径、请求方式等组合条件精准筛选流量。
10 | - 支持按筛选的流量比例灰度到目标节点。
11 | - 支持匹配请求头或query参数的请求流量灰度到目标节点。
12 | ## 更新日志
13 | ### V1.0(2023-4-30)
14 | - 插件上线
--------------------------------------------------------------------------------
/initialize/plugins/embed/strategy-grey.apinto.com/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/initialize/plugins/embed/strategy-grey.apinto.com/logo.png
--------------------------------------------------------------------------------
/initialize/plugins/embed/strategy-grey.apinto.com/plugin.yml:
--------------------------------------------------------------------------------
1 | id: "strategy-grey.apinto.com"
2 | name: "grey"
3 | cname: "灰度发布"
4 | resume: "灰度发布(又名金丝雀发布)是指在黑与白之间,能够平滑过渡的一种发布方式。当前支持通过流量比例、请求规则对请求进行灰度代理。"
5 | version: "v1.0.7"
6 | icon: "logo.png"
7 | driver: "strategy-grey.apinto.com"
8 | type: 2 #0为框架模块 1为核心模块 2为内置模块 3为非内置
9 | auto: true
10 | is_can_disable: true
11 | is_can_uninstall: false
12 | visible_in_navigation: true
13 | visible_in_market: true
14 | front: serv-governance
15 | navigation: "navigation.strategy"
16 | group_id: "strategy"
--------------------------------------------------------------------------------
/initialize/plugins/embed/strategy-traffic.apinto.com/README.md:
--------------------------------------------------------------------------------
1 | ## 基本介绍
2 | 限制单位时间内请求API的次数或数据大小,当达到限制条件时返回预设的信息。可用于限制特定用户的API调用量,或者避免上游服务因为流量过大而崩溃。
3 |
4 | ## 功能特性
5 | - 灵活的流量控制:可根据应用、IP、API、上游、请求路径、请求方式等方式筛选出需要限制的流量,比如限制
6 | - 支持多种时间单位来限制流量:每小时、每分钟、每秒
7 | - 可限制单位时间内请求的次数或数据大小(MB)
8 | - 达到限制条件时,支持自定义响应内容,支持JSON、XML、自定义文本
9 | ## 更新日志
10 | ### V1.0(2023-4-30)
11 | - 插件上线
--------------------------------------------------------------------------------
/initialize/plugins/embed/strategy-traffic.apinto.com/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/initialize/plugins/embed/strategy-traffic.apinto.com/logo.png
--------------------------------------------------------------------------------
/initialize/plugins/embed/strategy-traffic.apinto.com/plugin.yml:
--------------------------------------------------------------------------------
1 | id: "strategy-traffic.apinto.com"
2 | name: "traffic"
3 | cname: "流量限制"
4 | resume: "限制单位时间内请求API的次数或数据大小,当达到限制条件时返回预设的信息。可用于限制特定用户的API调用量,或者避免上游服务因为流量过大而崩溃。"
5 | version: "v1.0.7"
6 | icon: "logo.png"
7 | driver: "strategy-traffic.apinto.com"
8 | type: 2 #0为框架模块 1为核心模块 2为内置模块 3为非内置
9 | auto: true
10 | is_can_disable: true
11 | is_can_uninstall: false
12 | visible_in_navigation: true
13 | visible_in_market: true
14 | front: serv-governance
15 | navigation: "navigation.strategy"
16 | group_id: "strategy"
--------------------------------------------------------------------------------
/initialize/plugins/embed/strategy-visit.apinto.com/README.md:
--------------------------------------------------------------------------------
1 | ## 基本介绍
2 | API访问权限是指通过Apinto网关对API接口的访问进行授权和限制的一种机制,可以控制哪些用户、IP、API可以访问API接口以及他们可以访问哪些资源和数据。
3 |
4 | 通过API访问权限,可以保证API接口的安全性和稳定性,防止未经授权的用户、IP、API对API接口进行恶意访问或者滥用资源导致系统宕机或故障。
5 | ## 功能特性
6 | - 多维度筛选请求流量,用户可根据请求流量中属性:应用、IP、API、上游、请求路径、请求方式等组合条件精准筛选流量。
7 | - 支持设置黑名单和白名单。
8 | ## 更新日志
9 | ### V1.0(2023-4-30)
10 | - 插件上线
--------------------------------------------------------------------------------
/initialize/plugins/embed/strategy-visit.apinto.com/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/initialize/plugins/embed/strategy-visit.apinto.com/logo.png
--------------------------------------------------------------------------------
/initialize/plugins/embed/strategy-visit.apinto.com/plugin.yml:
--------------------------------------------------------------------------------
1 | id: "strategy-visit.apinto.com"
2 | name: "visit"
3 | cname: "API访问权限"
4 | resume: "保证API接口的安全性和稳定性,防止未经授权的用户、IP、API对API接口进行恶意访问或者滥用资源导致系统宕机或故障。"
5 | version: "v1.0.7"
6 | icon: "logo.png"
7 | driver: "strategy-visit.apinto.com"
8 | type: 2 #0为框架模块 1为核心模块 2为内置模块 3为非内置
9 | auto: true
10 | is_can_disable: true
11 | is_can_uninstall: false
12 | visible_in_navigation: true
13 | visible_in_market: true
14 | front: serv-governance
15 | navigation: "navigation.strategy"
16 | group_id: "strategy"
--------------------------------------------------------------------------------
/initialize/plugins/embed/upstream.apinto.com/README.md:
--------------------------------------------------------------------------------
1 | ## 基本介绍
2 | 在系统架构中,我们可以通过河流理论来判断上下游,最好方法是想象一条河。
3 | 1. 下游的水肯定是来自上游的。
4 | 2. 如果有人破坏了河的下游部分,那将对上游没有影响。
5 | 3. 如果有人破坏了河的上游部分,这将影响下游,即不会得到任何水。
6 |
7 | 以订单服务调用为例
8 |
9 | 
10 | 订单服务提供服务数据,是河流中的上游,软件A接受订单服务返回响应数据,作为河流中的下游。
11 |
12 | 为了保证上游服务的高可用及稳定性,一般来说,相同的上游服务会部署在多台机器/虚拟机中,通过增加机器/虚拟机的方式横向拓展,从而应对下游请求的流量高峰。
13 |
14 | 该插件将给Apinto网关配置上游服务信息,通过API绑定,实现完整转发流程。
15 | ## 功能特性
16 | - 支持配置负载均衡算法:IP Hash、带权轮询,合理分配上游服务压力,保证上游服务稳定性。
17 | - 支持引用环境变量,既统一了各环境各集群中上游服务的配置,又可以通过环境变量实现上游服务地址的差异化。
18 | - 支持会话保持,开启会话保持后,相同Session的请求将会转发到相同的上游服务地址,确保流程的连贯性。
19 |
20 | ## 更新日志
21 | ### V1.0(2023-4-30)
22 | - 插件上线
--------------------------------------------------------------------------------
/initialize/plugins/embed/upstream.apinto.com/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/initialize/plugins/embed/upstream.apinto.com/logo.png
--------------------------------------------------------------------------------
/initialize/plugins/embed/variable.apinto.com/README.md:
--------------------------------------------------------------------------------
1 | ## 基本介绍
2 | 环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数,是操作系统为了满足不同的应用场景预先在系统内预先设置的一大批全局变量。
3 |
4 | 环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性。此处定义的环境变量作用于网关集群中,在网关集群中全局生效。
5 |
6 | 项目部署环境一般可分为三种:生产环境,测试环境,开发环境,分别对应系统开发的三个阶段:开发->测试->上线。由于不同环境相互隔离的原因,不同环境一步部署了相同的上游服务业务,但上游服务地址一般是不同的。
7 |
8 | 我们可以通过环境变量的方式,在配置中引用相同的环境变量,设置不同环境不同集群中环境变量的值,以保证配置的一致性。
9 | ## 功能特性
10 | - 作用于网关集群,在网关集群中全局生效。
11 | - 支持在配置中引用环境变量,目前支持在上游服务中引用。
12 | ## 更新日志
13 | ### V1.0(2023-4-30)
14 | - 插件上线
--------------------------------------------------------------------------------
/initialize/plugins/embed/variable.apinto.com/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/initialize/plugins/embed/variable.apinto.com/logo.png
--------------------------------------------------------------------------------
/initialize/plugins/embed/variable.apinto.com/plugin.yml:
--------------------------------------------------------------------------------
1 | id: "variable.apinto.com"
2 | name: "variable"
3 | cname: "环境变量"
4 | resume: "通过环境变量的方式,在配置中引用相同的环境变量,设置不同环境不同集群中环境变量的值,以保证配置的一致性。"
5 | version: "v1.0.7"
6 | icon: "logo.png"
7 | driver: "variable.apinto.com"
8 | type: 1 #0为框架模块 1为核心模块 2为内置模块 3为非内置
9 | auto: true
10 | is_can_disable: false
11 | is_can_uninstall: false
12 | visible_in_navigation: true
13 | visible_in_market: true
14 | front: deploy
15 | navigation: "navigation.infrastructure"
16 | group_id: "core_module"
--------------------------------------------------------------------------------
/initialize/plugins/embed/webhook.apinto.com/README.md:
--------------------------------------------------------------------------------
1 | ## 基本介绍
2 | Webhook(又名钩子) 是一个 API 概念,是微服务 API 的使用范式之一,也被称为反向 API,即前端不主动发送请求,完全由后端推送。
3 |
4 | 简单来说,Webhook 就是一个接收 HTTP POST(或GET,PUT,DELETE)的URL,一个实现了 Webhook 的 API 提供商就是在当事件发生的时候会向这个配置好的 URL 发送一条信息,与请求-响应式不同,使用 Webhook 你可以实时接受到变化。
5 |
6 | 在配置前,使用者需要提供一个Webhook API,支持对接企业微信、飞书、钉钉等常用办公软件等消息通知API。
7 | 当Apinto触发特定事件时,如请求失败次数告警,监控程序将会按照配置的Webhook规则,推送事件信息到目标地址,实时发送告警信息。
8 | ## 功能特性
9 | - 配置Webhook规则,包括请求地址、请求方式、请求体模版格式
10 | - 当监控触发告警事件时,监控程序按照Webhhok规则发送请求到目标地址,实时发送告警信息。
11 | - 通过Webhook的自定义请求体模版特性,对接微信、飞书、钉钉等常用办公软件的消息通知API,
12 | ## 更新日志
13 | ### V1.0(2023-4-30)
14 | - 插件上线
--------------------------------------------------------------------------------
/initialize/plugins/embed/webhook.apinto.com/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eolinker/apinto-dashboard/e64b242c25afdfcdae37b95f89c32802a7da5903/initialize/plugins/embed/webhook.apinto.com/logo.png
--------------------------------------------------------------------------------
/initialize/plugins/embed/webhook.apinto.com/plugin.yml:
--------------------------------------------------------------------------------
1 | id: "webhook.apinto.com"
2 | name: "webhook"
3 | cname: "Webhook"
4 | resume: "自定义Webhook规则,当监控触发告警事件时,监控程序将会根据Webhook规则,推送信息到目标地址,实时发送告警信息。支持对接企业微信、飞书、钉钉等常用办公软件等消息通知API。"
5 | version: "v1.0.7"
6 | icon: "logo.png"
7 | driver: "webhook.apinto.com"
8 | type: 2 #0为框架模块 1为核心模块 2为内置模块 3为非内置
9 | auto: true
10 | is_can_disable: true
11 | is_can_uninstall: false
12 | visible_in_navigation: true
13 | visible_in_market: true
14 | front: system
15 | navigation: "navigation.system"
16 | group_id: "devops"
--------------------------------------------------------------------------------
/module/access-reader.go:
--------------------------------------------------------------------------------
1 | package apinto_module
2 |
3 | import "github.com/gin-gonic/gin"
4 |
5 | type AccessReaderHandler struct {
6 | accessOfPath map[string][]string
7 | }
8 |
9 | func (a *AccessReaderHandler) ReadAccess(ctx *gin.Context) {
10 | access, has := a.accessOfPath[ctx.FullPath()]
11 | if has {
12 | ctx.Set("access", access)
13 | }
14 | }
15 |
16 | type AccessReader struct {
17 | handler gin.HandlerFunc
18 | }
19 |
20 | func (a *AccessReader) ReadAccess(ctx *gin.Context) {
21 | if a.handler == nil {
22 | return
23 | }
24 | a.handler(ctx)
25 | }
26 |
--------------------------------------------------------------------------------
/module/middleware.go:
--------------------------------------------------------------------------------
1 | package apinto_module
2 |
3 | import (
4 | "context"
5 | "github.com/gin-gonic/gin"
6 | "net/http"
7 | )
8 |
9 | func GenHandleMiddleware(handle func(ctx context.Context, request *MiddlewareRequest, writer MiddlewareResponseWriter)) gin.HandlerFunc {
10 | return func(ginCtx *gin.Context) {
11 |
12 | request, err := Read(ginCtx.Request)
13 | if err != nil {
14 | ginCtx.AbortWithError(http.StatusServiceUnavailable, err)
15 | return
16 | }
17 |
18 | writer := new(MiddlewareResponse)
19 | handle(ginCtx, request, writer)
20 | ginCtx.JSON(http.StatusOK, writer)
21 |
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/module/options.go:
--------------------------------------------------------------------------------
1 | package apinto_module
2 |
3 | type IFilterOptionHandlerSupport interface {
4 | FilterOptionHandler() []IFilterOptionHandler
5 | }
6 | type FilterOptionConfig struct {
7 | Title string
8 |
9 | Titles []OptionTitle
10 | Key string
11 | }
12 | type IFilterValue struct {
13 | }
14 | type IFilterOptionHandler interface {
15 | Name() string
16 | Config() FilterOptionConfig
17 | GetOptions(namespaceId int, keyword, groupUUID string, pageNum, pageSize int) ([]any, int)
18 | Labels(namespaceId int, values ...string) []string
19 | Label(namespaceId int, value string) string
20 | }
21 |
22 | type OptionTitle struct {
23 | Field string `json:"field"`
24 | Title string `json:"title"`
25 | }
26 |
27 | type IFilterOptionHandlerManager interface {
28 | ResetFilterOptionHandlers(handlers map[string]IFilterOptionHandler)
29 | }
30 |
--------------------------------------------------------------------------------
/module/plugin.go:
--------------------------------------------------------------------------------
1 | package apinto_module
2 |
3 | type Plugin interface {
4 | CreateModule(name string, config interface{}) (Module, error)
5 | CheckConfig(name string, config interface{}) error
6 | GetPluginFrontend(moduleName string) string
7 | IsShowServer() bool
8 | }
9 |
--------------------------------------------------------------------------------
/module/response-update_test.go:
--------------------------------------------------------------------------------
1 | package apinto_module
2 |
3 | import (
4 | "fmt"
5 | _ "github.com/stretchr/testify/assert"
6 | )
7 |
8 | func ExampleDoEvent() {
9 | type args struct {
10 | event string
11 | v any
12 | }
13 | type testCase struct {
14 | name string
15 | args args
16 | }
17 | tests := []testCase{
18 | {
19 | name: "login",
20 | args: args{
21 | event: "login",
22 | v: "username=a&nickname=b",
23 | },
24 | },
25 | }
26 | RegisterEventHandler("login", func(event string, v any) {
27 | fmt.Printf("get event %s:%s", event, v)
28 | })
29 | for _, tt := range tests {
30 |
31 | DoEvent(tt.args.event, tt.args.v)
32 |
33 | }
34 | //output: get event login:username=a&nickname=b
35 | }
36 |
--------------------------------------------------------------------------------
/module/simple.go:
--------------------------------------------------------------------------------
1 | package apinto_module
2 |
--------------------------------------------------------------------------------
/modules/api/api-entry/api_history.go:
--------------------------------------------------------------------------------
1 | package api_entry
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/modules/base/history-entry"
5 | "time"
6 | )
7 |
8 | type ApiHistory struct {
9 | Id int
10 | ApiId int
11 | NamespaceId int
12 | OldValue ApiHistoryInfo
13 | NewValue ApiHistoryInfo
14 | OptType history_entry.OptType //1新增 2修改 3删除
15 | OptTime time.Time
16 | Operator int
17 | }
18 |
19 | type ApiHistoryInfo struct {
20 | Api API `json:"api"`
21 | Config APIVersionConfig `json:"config"`
22 | }
23 |
--------------------------------------------------------------------------------
/modules/api/api-entry/api_runtime.go:
--------------------------------------------------------------------------------
1 | package api_entry
2 |
3 | import "time"
4 |
5 | type APIRuntime struct {
6 | Id int
7 | NamespaceId int
8 | ApiID int
9 | ClusterID int
10 | VersionID int
11 | IsOnline bool
12 | Disable bool
13 | Operator int
14 | CreateTime time.Time
15 | UpdateTime time.Time
16 | }
17 |
--------------------------------------------------------------------------------
/modules/api/api-entry/api_stat.go:
--------------------------------------------------------------------------------
1 | package api_entry
2 |
3 | type APIStat struct {
4 | APIID int
5 | VersionID int
6 | }
7 |
--------------------------------------------------------------------------------
/modules/api/api-entry/publish_history.go:
--------------------------------------------------------------------------------
1 | package api_entry
2 |
3 | import "time"
4 |
5 | type ApiPublishHistory struct {
6 | Id int
7 | VersionName string
8 | ClusterId int
9 | NamespaceId int
10 | Desc string
11 | VersionId int
12 | Target int
13 | APIVersionConfig
14 | OptType int
15 | Operator int
16 | OptTime time.Time
17 | }
18 |
--------------------------------------------------------------------------------
/modules/api/service/api-driver.go:
--------------------------------------------------------------------------------
1 | package api_service
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/driver"
5 | "github.com/eolinker/apinto-dashboard/modules/api"
6 | )
7 |
8 | const (
9 | DriverApiHTTP = "http"
10 | DriverWebsocket = "websocket"
11 | )
12 |
13 | type apiDriver struct {
14 | *driver.DriverManager[api.IAPIDriver]
15 | }
16 |
17 | func (d *apiDriver) List() []*api.APIDriverInfo {
18 | list := make([]*api.APIDriverInfo, 0)
19 | for name, _ := range d.Drivers() {
20 | list = append(list, &api.APIDriverInfo{
21 | Name: name,
22 | })
23 | }
24 | return list
25 | }
26 |
27 | func newAPIDriverManager() api.IAPIDriverManager {
28 | return &apiDriver{DriverManager: driver.CreateDriverManager[api.IAPIDriver]()}
29 | }
30 |
--------------------------------------------------------------------------------
/modules/api/service/batch_online_api.go:
--------------------------------------------------------------------------------
1 | package api_service
2 |
3 | import (
4 | "fmt"
5 | "github.com/eolinker/apinto-dashboard/cache"
6 | apimodel "github.com/eolinker/apinto-dashboard/modules/api/model"
7 | "time"
8 | )
9 |
10 | type IBatchOnlineApiTaskCache interface {
11 | cache.IRedisCache[apimodel.BatchOnlineCheckTask, string]
12 | }
13 |
14 | type batchOnlineApiTaskCache struct {
15 | cache.IRedisCache[apimodel.BatchOnlineCheckTask, string]
16 | }
17 |
18 | func formatKey(token string) string {
19 | return fmt.Sprintf("batch_online_api_token:%s", token)
20 | }
21 |
22 | func newBatchOnlineTaskCache() IBatchOnlineApiTaskCache {
23 |
24 | return &batchOnlineApiTaskCache{
25 | IRedisCache: cache.CreateRedisCache[apimodel.BatchOnlineCheckTask](time.Hour*8, formatKey),
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/modules/api/service/import_api_data.go:
--------------------------------------------------------------------------------
1 | package api_service
2 |
3 | import (
4 | "fmt"
5 | "github.com/eolinker/apinto-dashboard/cache"
6 | apimodel "github.com/eolinker/apinto-dashboard/modules/api/model"
7 | "time"
8 | )
9 |
10 | type IImportApiCache interface {
11 | cache.IRedisCache[apimodel.ImportAPIRedisData, string]
12 | }
13 |
14 | func importKey(token string) string {
15 | return fmt.Sprintf("import_api_token:%s", token)
16 | }
17 |
18 | func newImportCache() IImportApiCache {
19 | cacheInfo := cache.CreateRedisCache[apimodel.ImportAPIRedisData, string](time.Hour*8, importKey)
20 |
21 | return cacheInfo
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/modules/api/status-code/code.go:
--------------------------------------------------------------------------------
1 | package status_code
2 |
3 | const (
4 | ApiModuleBaseErrCode = 101000
5 | ApiConfigBindErr = ApiModuleBaseErrCode + iota
6 | ApiSchemeNotExist
7 | ApiConfigCheckErr
8 | ApiRouterReduplicatedErr
9 | ApiGroupNotExistErr
10 | ApiServiceNotExistErr
11 | ApiTemplateNotExistErr
12 | ApiDataBaseErr
13 | )
14 |
--------------------------------------------------------------------------------
/modules/api/store/init.go:
--------------------------------------------------------------------------------
1 | package api_store
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/store"
5 | "github.com/eolinker/eosc/common/bean"
6 | )
7 |
8 | func InitStoreDB(db store.IDB) {
9 | api := NewAPIStore(db)
10 | apiStat := NewAPIStatStore(db)
11 | apiVersion := newAPIVersionStore(db)
12 | apiHistory := newApiHistoryStore(db)
13 | apiPublishHistory := newApiPublishHistoryStore(db)
14 |
15 | bean.Injection(&api)
16 | bean.Injection(&apiStat)
17 | bean.Injection(&apiVersion)
18 | bean.Injection(&apiHistory)
19 | bean.Injection(&apiPublishHistory)
20 | }
21 |
--------------------------------------------------------------------------------
/modules/application/application-entry/application_auth_publish.go:
--------------------------------------------------------------------------------
1 | package application_entry
2 |
3 | import "time"
4 |
5 | type AppPublishHistory struct {
6 | Id int
7 | VersionName string
8 | ClusterId int
9 | NamespaceId int
10 | Desc string
11 | VersionId int
12 | Target int
13 | ApplicationVersionConfig
14 | OptType int
15 | Operator int
16 | OptTime time.Time
17 | }
18 |
--------------------------------------------------------------------------------
/modules/application/application-model/application_auth.go:
--------------------------------------------------------------------------------
1 | package application_model
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/modules/application/application-entry"
5 | "time"
6 | )
7 |
8 | type ApplicationAuth struct {
9 | *application_entry.ApplicationAuth
10 | Operator string
11 | ParamPosition string
12 | ParamName string
13 | ParamInfo string
14 | RuleInfo string //规则信息
15 | Config string //配置信息
16 | }
17 |
18 | type AppAuthItem struct {
19 | UUID string
20 | Title string
21 | Driver string
22 | Operator string
23 | HideCredential bool
24 | ExpireTime int64
25 | UpdateTime time.Time
26 | }
27 |
28 | type AuthDetailItem struct {
29 | Key string `json:"key"`
30 | Value string `json:"value"`
31 | }
32 |
--------------------------------------------------------------------------------
/modules/application/application-service/auth.go:
--------------------------------------------------------------------------------
1 | package application_service
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/driver"
5 | "github.com/eolinker/apinto-dashboard/modules/application"
6 | )
7 |
8 | type authDriver struct {
9 | *driver.DriverManager[application.IAuthDriver]
10 | }
11 |
12 | func newAuthDriverManager() application.IAuthDriverManager {
13 | return &authDriver{DriverManager: driver.CreateDriverManager[application.IAuthDriver]()}
14 | }
15 |
16 | func (d *authDriver) List() []*driver.DriverInfo {
17 | list := make([]*driver.DriverInfo, 0)
18 | for name, value := range d.Drivers() {
19 | list = append(list, &driver.DriverInfo{
20 | Name: name,
21 | Render: value.Render(),
22 | })
23 | }
24 | return list
25 | }
26 |
--------------------------------------------------------------------------------
/modules/application/application-service/driver.go:
--------------------------------------------------------------------------------
1 | package application_service
2 |
3 | const (
4 | DriverBasic = "basic"
5 | DriverApikey = "apikey"
6 | DriverAKsK = "aksk"
7 | DriverJwt = "jwt"
8 | )
9 |
--------------------------------------------------------------------------------
/modules/application/application-service/init.go:
--------------------------------------------------------------------------------
1 | package application_service
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/modules/application/driver"
5 | "github.com/eolinker/eosc/common/bean"
6 | )
7 |
8 | func init() {
9 | apikey := driver.CreateApikey()
10 | aksk := driver.CreateAkSk()
11 | jwt := driver.CreateJwt()
12 | basic := driver.CreateBasic()
13 |
14 | authDriverManager := newAuthDriverManager()
15 | authDriverManager.RegisterDriver(DriverApikey, apikey)
16 | authDriverManager.RegisterDriver(DriverAKsK, aksk)
17 | authDriverManager.RegisterDriver(DriverJwt, jwt)
18 | authDriverManager.RegisterDriver(DriverBasic, basic)
19 |
20 | bean.Injection(&authDriverManager)
21 |
22 | application := newApplicationService()
23 |
24 | bean.Injection(&application)
25 | }
26 |
--------------------------------------------------------------------------------
/modules/application/application-store/init.go:
--------------------------------------------------------------------------------
1 | package application_store
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/store"
5 | "github.com/eolinker/eosc/common/bean"
6 | )
7 |
8 | func init() {
9 | store.RegisterStore(func(db store.IDB) {
10 | application := newApplicationStore(db)
11 | applicationStat := newApplicationStatStore(db)
12 | applicationVersion := newApplicationVersionStore(db)
13 | applicationAuth := newApplicationAuthStore(db)
14 | applicationHistory := newApplicationHistoryStore(db)
15 | appPublishHistory := newAppPublishHistoryStore(db)
16 |
17 | bean.Injection(&application)
18 | bean.Injection(&applicationVersion)
19 | bean.Injection(&applicationStat)
20 | bean.Injection(&applicationAuth)
21 | bean.Injection(&applicationHistory)
22 | bean.Injection(&appPublishHistory)
23 | })
24 | }
25 |
--------------------------------------------------------------------------------
/modules/application/driver/common.go:
--------------------------------------------------------------------------------
1 | package driver
2 |
3 | type AuthConfig struct {
4 | AkSkConfig
5 | JwtConfig
6 | ApikeyConfig
7 | BasicConfig
8 | }
9 |
--------------------------------------------------------------------------------
/modules/audit/audit-service/init.go:
--------------------------------------------------------------------------------
1 | package audit_service
2 |
3 | import "github.com/eolinker/eosc/common/bean"
4 |
5 | func init() {
6 | auditLog := newAuditLogService()
7 | bean.Injection(&auditLog)
8 | }
9 |
--------------------------------------------------------------------------------
/modules/audit/audit-store/init.go:
--------------------------------------------------------------------------------
1 | package audit_store
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/store"
5 | "github.com/eolinker/eosc/common/bean"
6 | )
7 |
8 | func init() {
9 | store.RegisterStore(func(db store.IDB) {
10 | auditLog := newAuditLogStore(db)
11 | bean.Injection(&auditLog)
12 | })
13 | }
14 |
--------------------------------------------------------------------------------
/modules/audit/audit.go:
--------------------------------------------------------------------------------
1 | package audit
2 |
3 | import (
4 | "context"
5 | "github.com/eolinker/apinto-dashboard/modules/audit/audit-model"
6 | "time"
7 | )
8 |
9 | type IAuditLogService interface {
10 | GetLogsList(ctx context.Context, namespaceID, operateType int, kind, keyword string, start, end int64, pageNum, pageSize int) ([]*audit_model.LogListItem, int, error)
11 | GetLogDetail(ctx context.Context, logID int) ([]*audit_model.LogDetailArg, error)
12 | Log(namespace int, userId int, operate int, kind string, url, object, ip, userAgent, body, err string, start, end time.Time)
13 | }
14 |
--------------------------------------------------------------------------------
/modules/base/env-model/cluster_enum.go:
--------------------------------------------------------------------------------
1 | package env_model
2 |
3 | import "fmt"
4 |
5 | type EnumEnv int
6 |
7 | const (
8 | EnumEnvNone = iota
9 | EnumEnvPRO
10 | EnumEnvFAT
11 | EnumEnvDEV
12 | EnumEnvUAT
13 | EnumEnvAll
14 | )
15 |
16 | var (
17 | enumValueNames = map[EnumEnv]string{
18 | EnumEnvNone: "NONE",
19 | EnumEnvPRO: "PRO",
20 | EnumEnvFAT: "FAT",
21 | EnumEnvDEV: "DEV",
22 | EnumEnvUAT: "UAT",
23 | }
24 | EnumValueList = []EnumEnv{EnumEnvPRO, EnumEnvFAT, EnumEnvDEV, EnumEnvUAT}
25 | )
26 |
27 | type EnumEnvOut struct {
28 | Name string `json:"name"`
29 | Value EnumEnv `json:"value"`
30 | }
31 |
32 | func (e EnumEnv) MarshalJSON() ([]byte, error) {
33 | return []byte(fmt.Sprint("\"", e.String(), "\"")), nil
34 | }
35 |
36 | func (e EnumEnv) String() string {
37 | if e >= EnumEnvAll {
38 | return "unknown"
39 | }
40 | return enumValueNames[e]
41 | }
42 |
--------------------------------------------------------------------------------
/modules/base/frontend-model/frontend.go:
--------------------------------------------------------------------------------
1 | package frontend_model
2 |
3 | type RouterName string
4 |
5 | var (
6 | RouterNameClusterVariable RouterName = "deploy/cluster/content" //cluster_name
7 | RouterNameDiscoveryOnline RouterName = "upstream/serv-discovery/content" //discovery_name
8 | RouterNameServiceOnline RouterName = "template/upstream"
9 | RouterNameTemplateOnline RouterName = "router/plugin-template/content"
10 | RouterNameClusterPlugin RouterName = "deploy/cluster/content/plugin"
11 | )
12 |
13 | type Router struct {
14 | Name RouterName `json:"name"`
15 | Params map[string]string `json:"params"`
16 | Msg string `json:"msg,omitempty"`
17 | }
18 |
--------------------------------------------------------------------------------
/modules/base/locker-service/init.go:
--------------------------------------------------------------------------------
1 | package locker_service
2 |
3 | import "github.com/eolinker/eosc/common/bean"
4 |
5 | func init() {
6 | lockAsynService := NewAsynLockService()
7 | lockSyncService := NewSyncLockService()
8 | bean.Injection(&lockAsynService)
9 | bean.Injection(&lockSyncService)
10 | }
11 |
--------------------------------------------------------------------------------
/modules/base/quote-store/init.go:
--------------------------------------------------------------------------------
1 | package quote_store
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/store"
5 | "github.com/eolinker/eosc/common/bean"
6 | )
7 |
8 | func init() {
9 | store.RegisterStore(func(db store.IDB) {
10 | quote := newQuoteStore(db)
11 | bean.Injection("e)
12 | })
13 | }
14 |
--------------------------------------------------------------------------------
/modules/base/stat-entry/stat.go:
--------------------------------------------------------------------------------
1 | package stat_entry
2 |
3 | // Stat 最新版本关联表
4 | type Stat struct {
5 | ID int `gorm:"type:int(11);size:11;not null;auto_increment;primary_key;column:id;comment:主键ID"`
6 | Kind string `gorm:"size:20;not null;column:kind;uniqueIndex:kind;comment:根据kind区分是哪个表的ID"`
7 | Tag int `gorm:"type:int(11);size:11;not null;column:target;uniqueIndex:kind"`
8 | Version int `gorm:"type:int(11);size:11;not null;column:version;comment:版本ID"`
9 | }
10 |
11 | func (s *Stat) IdValue() int {
12 | return s.ID
13 | }
14 |
15 | func (*Stat) TableName() string {
16 | return "stat"
17 | }
18 |
--------------------------------------------------------------------------------
/modules/cluster/cluster-dto/cluster_certificate.go:
--------------------------------------------------------------------------------
1 | package cluster_dto
2 |
3 | type ClusterCertificateInput struct {
4 | Key string `json:"key"`
5 | Pem string `json:"pem"`
6 | }
7 |
8 | type ClusterCertificateOut struct {
9 | Id int `json:"id"`
10 | ClusterId int `json:"cluster_id"`
11 | Name string `json:"name"`
12 | DNSName []string `json:"dns_name"`
13 | OperatorName string `json:"operator"`
14 | ValidTime string `json:"valid_time"`
15 | CreateTime string `json:"create_time"`
16 | UpdateTime string `json:"update_time"`
17 | }
18 |
--------------------------------------------------------------------------------
/modules/cluster/cluster-dto/cluster_node.go:
--------------------------------------------------------------------------------
1 | package cluster_dto
2 |
3 | import "github.com/eolinker/apinto-dashboard/enum"
4 |
5 | type ClusterNode struct {
6 | Name string `json:"name"`
7 | ServiceAddr string `json:"service_addr"`
8 | AdminAddr string `json:"admin_addr"`
9 | Status enum.ClusterNodeStatus `json:"status"`
10 | }
11 |
12 | type ClusterNodeSimple struct {
13 | Name string `json:"name"`
14 | }
15 | type ClusterNodeInput struct {
16 | Source string `json:"source"`
17 | ClusterAddr string `json:"cluster_addr"`
18 | }
19 |
--------------------------------------------------------------------------------
/modules/cluster/cluster-entry/cluster_config_runtime.go:
--------------------------------------------------------------------------------
1 | package cluster_entry
2 |
3 | import "time"
4 |
5 | type ClusterConfigRuntime struct {
6 | Id int
7 | NamespaceId int
8 | ConfigID int
9 | ClusterId int
10 | IsOnline bool
11 | Operator int
12 | CreateTime time.Time
13 | UpdateTime time.Time
14 | }
15 |
--------------------------------------------------------------------------------
/modules/cluster/cluster-model/cluster.go:
--------------------------------------------------------------------------------
1 | package cluster_model
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/modules/cluster/cluster-entry"
5 | )
6 |
7 | type Cluster struct {
8 | *cluster_entry.Cluster
9 | Status int //1正常 2部分正常 3异常
10 | }
11 |
12 | //func (c *Cluster) GetName() string {
13 | // return c.Name
14 | //}
15 | //
16 | //func (c *Cluster) GetAddr() string {
17 | // return c.Addr
18 | //}
19 |
20 | type ClusterSimple struct {
21 | Name string `json:"name"`
22 | Title string `json:"title"`
23 | Env string `json:"env"`
24 | }
25 |
--------------------------------------------------------------------------------
/modules/cluster/cluster-model/cluster_certificate.go:
--------------------------------------------------------------------------------
1 | package cluster_model
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/modules/cluster/cluster-entry"
5 | )
6 |
7 | type ClusterCertificate struct {
8 | *cluster_entry.ClusterCertificate
9 | ClusterName string
10 | OperatorName string
11 | }
12 |
13 | type Certificate struct {
14 | ID int `json:"id"`
15 | Name string `json:"name"`
16 | DnsName []string `json:"dns_name"`
17 | Key string `json:"key"`
18 | Pem string `json:"pem"`
19 | ValidTime string `json:"valid_time"`
20 | }
21 |
--------------------------------------------------------------------------------
/modules/cluster/cluster-service/node_cache.go:
--------------------------------------------------------------------------------
1 | package cluster_service
2 |
3 | import (
4 | "fmt"
5 | "github.com/eolinker/apinto-dashboard/cache"
6 | "github.com/eolinker/apinto-dashboard/modules/cluster/cluster-model"
7 | "time"
8 | )
9 |
10 | type INodeCache interface {
11 | cache.IRedisCache[[]*cluster_model.Node, int]
12 | }
13 |
14 | func installedCacheKey(clusterId int) string {
15 | return fmt.Sprintf("cluster_%d_nodes", clusterId)
16 | }
17 |
18 | func newINodeCache() INodeCache {
19 | return cache.CreateRedisCache[[]*cluster_model.Node, int](5*time.Minute, installedCacheKey)
20 | }
21 |
--------------------------------------------------------------------------------
/modules/core/controller/env.go:
--------------------------------------------------------------------------------
1 | package controller
2 |
3 | import (
4 | apinto_module "github.com/eolinker/apinto-dashboard/module"
5 | env_controller "github.com/eolinker/apinto-dashboard/modules/base/env-controller"
6 | "net/http"
7 | )
8 |
9 | func envEnumRouters() apinto_module.RoutersInfo {
10 | ec := env_controller.NewEnumController()
11 | return apinto_module.RoutersInfo{
12 | {
13 | Method: http.MethodGet,
14 | Path: "/api/enum/envs",
15 | HandlerFunc: []apinto_module.HandlerFunc{ec.GetEnv},
16 | },
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/modules/core/controller/expire.go:
--------------------------------------------------------------------------------
1 | package controller
2 |
--------------------------------------------------------------------------------
/modules/core/controller/report.go:
--------------------------------------------------------------------------------
1 | package controller
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/controller"
5 | "github.com/eolinker/apinto-dashboard/report"
6 | "github.com/gin-gonic/gin"
7 | "net/http"
8 | )
9 |
10 | func (m *Module) reportStatus(ginCtx *gin.Context) {
11 | consoleId, nodes, need := report.NeedReport()
12 | if !need {
13 | ginCtx.JSON(http.StatusOK, controller.NewSuccessResult(map[string]interface{}{
14 | "report": "no",
15 | }))
16 |
17 | return
18 | }
19 | ginCtx.JSON(http.StatusOK, controller.NewSuccessResult(map[string]interface{}{
20 | "report": "yes",
21 | "id": consoleId,
22 | "nodes": nodes,
23 | }))
24 |
25 | }
26 |
27 | func (m *Module) updateReport(ginCtx *gin.Context) {
28 | report.UpdateReport()
29 | ginCtx.JSON(http.StatusOK, controller.NewSuccessResult(nil))
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/modules/core/model/navigation.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | type Navigation struct {
4 | Title string `json:"title"`
5 | Icon string `json:"icon"`
6 | //IconType string `json:"icon_type"`
7 | Modules []*Module `json:"modules"`
8 | Default string `json:"default"`
9 | }
10 |
11 | type Module struct {
12 | Name string `json:"name"`
13 | Title string `json:"title"`
14 | //Type string `json:"type"`
15 | Path string `json:"path"`
16 | }
17 |
--------------------------------------------------------------------------------
/modules/core/service.go:
--------------------------------------------------------------------------------
1 | package core
2 |
3 | import (
4 | "context"
5 | "github.com/eolinker/apinto-dashboard/modules/core/model"
6 | "github.com/gin-gonic/gin"
7 | "net/http"
8 | )
9 |
10 | type ICore interface {
11 | http.Handler
12 | ResetVersion(version string)
13 | ReloadModule() error
14 | CheckNewModule(uuid, name, driver string, define, config interface{}) error
15 | HasModule(module string, path string) bool
16 | }
17 |
18 | type EngineCreate interface {
19 | CreateEngine() (engine *gin.Engine)
20 | }
21 | type INavigationService interface {
22 | List(ctx context.Context) ([]*model.Navigation, map[string]string, error)
23 | }
24 |
--------------------------------------------------------------------------------
/modules/core/service/init.go:
--------------------------------------------------------------------------------
1 | package service
2 |
3 | import (
4 | apinto_module "github.com/eolinker/apinto-dashboard/module"
5 | "github.com/eolinker/eosc/common/bean"
6 | )
7 |
8 | func init() {
9 | navigationService := newNavigationService()
10 | bean.Injection(&navigationService)
11 |
12 | providerService := NewProviderService()
13 |
14 | var iProviders apinto_module.IProviders = providerService
15 | bean.Injection(&iProviders)
16 | iCore := NewService(providerService)
17 | bean.Injection(&iCore)
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/modules/dynamic/dynamic-dto/cluster.go:
--------------------------------------------------------------------------------
1 | package dynamic_dto
2 |
3 | type Cluster struct {
4 | Cluster []string `json:"cluster"`
5 | }
6 |
--------------------------------------------------------------------------------
/modules/dynamic/dynamic-entry/dynamic_publish_history.go:
--------------------------------------------------------------------------------
1 | package dynamic_entry
2 |
3 | import "time"
4 |
5 | type DynamicPublishHistory struct {
6 | Id int
7 | VersionName string
8 | ClusterId int
9 | NamespaceId int
10 | Target int
11 | Desc string
12 | VersionId int
13 | Publish *DynamicPublishConfig //此次发布的数据
14 | OptType int
15 | Operator int
16 | CreateTime time.Time
17 | }
18 |
--------------------------------------------------------------------------------
/modules/dynamic/dynamic-entry/dynamic_quote.go:
--------------------------------------------------------------------------------
1 | package dynamic_entry
2 |
3 | type DynamicQuote struct {
4 | Id int `gorm:"column:id;type:INT(11);AUTO_INCREMENT;NOT NULL;comment:主键ID"`
5 | Namespace int `gorm:"column:namespace;type:INT(11);NOT NULL;comment:工作空间"`
6 | Source string `gorm:"column:source;type:VARCHAR(255);NOT NULL;comment:源name"`
7 | Target string `gorm:"column:target;type:VARCHAR(255);NOT NULL;comment:依赖name"`
8 | }
9 |
10 | func (d *DynamicQuote) TableName() string {
11 | return "dynamic_quote"
12 | }
13 |
14 | func (d *DynamicQuote) IdValue() int {
15 | return d.Id
16 | }
17 |
--------------------------------------------------------------------------------
/modules/dynamic/dynamic-model/render.go:
--------------------------------------------------------------------------------
1 | package dynamic_model
2 |
3 | type DynamicModuleRender struct {
4 | *DynamicBasicInfo
5 | Render map[string]interface{} `json:"render"`
6 | }
7 |
--------------------------------------------------------------------------------
/modules/dynamic/dynamic-service/init.go:
--------------------------------------------------------------------------------
1 | package dynamic_service
2 |
3 | import "github.com/eolinker/eosc/common/bean"
4 |
5 | func init() {
6 | ds := newDynamicService()
7 | bean.Injection(&ds)
8 | }
9 |
--------------------------------------------------------------------------------
/modules/dynamic/dynamic-store/dynamic_quote.go:
--------------------------------------------------------------------------------
1 | package dynamic_store
2 |
3 | import (
4 | dynamic_entry "github.com/eolinker/apinto-dashboard/modules/dynamic/dynamic-entry"
5 | "github.com/eolinker/apinto-dashboard/store"
6 | )
7 |
8 | type IDynamicQuoteStore interface {
9 | store.IBaseStore[dynamic_entry.DynamicQuote]
10 | }
11 |
12 | type dynamicQuoteStore struct {
13 | *store.BaseStore[dynamic_entry.DynamicQuote]
14 | }
15 |
16 | func newDynamicQuoteStore(db store.IDB) IDynamicQuoteStore {
17 | return &dynamicQuoteStore{BaseStore: store.CreateStore[dynamic_entry.DynamicQuote](db)}
18 | }
19 |
--------------------------------------------------------------------------------
/modules/dynamic/dynamic-store/init.go:
--------------------------------------------------------------------------------
1 | package dynamic_store
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/store"
5 | "github.com/eolinker/eosc/common/bean"
6 | )
7 |
8 | var (
9 | kind = "dynamic_module"
10 | )
11 |
12 | func init() {
13 | store.RegisterStore(func(db store.IDB) {
14 | dynamic := newDynamicStore(db)
15 | dynamicQuote := newDynamicQuoteStore(db)
16 | dynamicPublishHistory := NewDynamicPublishHistoryStore(db, kind)
17 | dynamicPublishVersion := NewDynamicPublishVersionStore(db, kind)
18 | bean.Injection(&dynamic)
19 | bean.Injection(&dynamicQuote)
20 | bean.Injection(&dynamicPublishHistory)
21 | bean.Injection(&dynamicPublishVersion)
22 | })
23 | }
24 |
--------------------------------------------------------------------------------
/modules/email/dto/email.go:
--------------------------------------------------------------------------------
1 | package dto
2 |
3 | type EmailInput struct {
4 | Uuid string `json:"uuid"`
5 | SmtpUrl string `json:"smtp_url"`
6 | SmtpPort int `json:"smtp_port"`
7 | Protocol string `json:"protocol"`
8 | Email string `json:"email"`
9 | Account string `json:"account"`
10 | Password string `json:"password"`
11 | }
12 |
13 | type EmailOutput struct {
14 | Uuid string `json:"uuid"`
15 | SmtpUrl string `json:"smtp_url"`
16 | SmtpPort int `json:"smtp_port"`
17 | Protocol string `json:"protocol"`
18 | Email string `json:"email"`
19 | Account string `json:"account"`
20 | Password string `json:"password"`
21 | }
22 |
--------------------------------------------------------------------------------
/modules/group/group-model/common_group.go:
--------------------------------------------------------------------------------
1 | package group_model
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/modules/group/group-entry"
5 | )
6 |
7 | type CommonGroupRoot struct {
8 | UUID string
9 | Name string
10 | CommonGroup []*CommonGroup
11 | }
12 |
13 | type CommonGroup struct {
14 | Group *group_entry.CommonGroup
15 | Subgroup []*CommonGroup
16 | }
17 |
18 | type CommonGroupApi struct {
19 | Path string
20 | PathLabel string
21 | Name string
22 | UUID string
23 | Methods []string
24 | GroupUUID string
25 | }
26 |
27 | type CommonGroupBasic struct {
28 | Uuid string
29 | Type string
30 | TagID int
31 | Name string
32 | ParentId int
33 | Sort int
34 | }
35 |
--------------------------------------------------------------------------------
/modules/group/group-service/init.go:
--------------------------------------------------------------------------------
1 | package group_service
2 |
3 | import "github.com/eolinker/eosc/common/bean"
4 |
5 | func init() {
6 | group := newCommonGroupService()
7 |
8 | bean.Injection(&group)
9 | }
10 |
--------------------------------------------------------------------------------
/modules/group/group-store/init.go:
--------------------------------------------------------------------------------
1 | package group_store
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/store"
5 | "github.com/eolinker/eosc/common/bean"
6 | )
7 |
8 | func init() {
9 | store.RegisterStore(func(db store.IDB) {
10 | commonGroup := newCommonGroupStore(db)
11 |
12 | bean.Injection(&commonGroup)
13 | })
14 | }
15 |
--------------------------------------------------------------------------------
/modules/grpc-service/service/cache.go:
--------------------------------------------------------------------------------
1 | package service
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/cache"
5 | grpc_service "github.com/eolinker/apinto-dashboard/grpc-service"
6 | "time"
7 | )
8 |
9 | type INavigationModulesCache interface {
10 | cache.IRedisCache[grpc_service.NavigationModulesResp, string]
11 | }
12 |
13 | func navigationModulesCacheKey(string) string {
14 | return "navigation_modules"
15 | }
16 |
17 | func newNavigationModulesCache() INavigationModulesCache {
18 | return cache.CreateRedisCache[grpc_service.NavigationModulesResp](time.Hour, navigationModulesCacheKey)
19 | }
20 |
--------------------------------------------------------------------------------
/modules/grpc-service/service/error.go:
--------------------------------------------------------------------------------
1 | package service
2 |
3 | type SendMsgError struct {
4 | UUID string `json:"uuid"`
5 | NoticeChannelUUID string `json:"notice_channel_uuid"`
6 | Msg string `json:"msg"`
7 | }
8 |
--------------------------------------------------------------------------------
/modules/grpc-service/service/init.go:
--------------------------------------------------------------------------------
1 | package service
2 |
3 | import (
4 | "github.com/eolinker/eosc/common/bean"
5 | )
6 |
7 | func init() {
8 | iInstalledCache := newNavigationModulesCache()
9 | bean.Injection(&iInstalledCache)
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/modules/log/dto/arg.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
3 | * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
4 | * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
5 | * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
6 | * Vestibulum commodo. Ut rhoncus gravida arcu.
7 | */
8 |
9 | package dto
10 |
11 | type Args string
12 |
--------------------------------------------------------------------------------
/modules/log/dto/output.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
3 | * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
4 | * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
5 | * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
6 | * Vestibulum commodo. Ut rhoncus gravida arcu.
7 | */
8 |
9 | package dto
10 |
11 | type Output struct {
12 | Name string `json:"name"`
13 | TailKey string `json:"tail"`
14 | Files []File `json:"files"`
15 | }
16 | type File struct {
17 | File string `json:"file,omitempty"`
18 | Size string `json:"size,omitempty"`
19 | Mod string `json:"mod,omitempty"`
20 | Key string `json:"key,omitempty"`
21 | }
22 |
--------------------------------------------------------------------------------
/modules/log/module/conn.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package module
6 |
7 | import (
8 | "bufio"
9 | "net"
10 | )
11 |
12 | // The Conn type represents a WebSocket connection.
13 | type Conn struct {
14 | net.Conn
15 | readBuf *bufio.Reader
16 | }
17 |
18 | func (c *Conn) Read(p []byte) (int, error) {
19 | return c.readBuf.Read(p)
20 | }
21 |
--------------------------------------------------------------------------------
/modules/module-plugin/entry/module_plugin_package.go:
--------------------------------------------------------------------------------
1 | package entry
2 |
3 | type ModulePluginPackage struct {
4 | Id int `gorm:"column:id;type:int(11);autoIncrement:false;primary_key;comment:模块插件表的主键ID" json:"id"`
5 | Package []byte `gorm:"column:package;type:mediumblob;not null;comment:安装包" json:"package"`
6 | }
7 |
8 | func (*ModulePluginPackage) TableName() string {
9 | return "module_plugin_package"
10 | }
11 |
12 | func (c *ModulePluginPackage) IdValue() int {
13 | return c.Id
14 | }
15 |
--------------------------------------------------------------------------------
/modules/module-plugin/entry/module_plugin_resources.go:
--------------------------------------------------------------------------------
1 | package entry
2 |
3 | type PluginResources struct {
4 | ID int `gorm:"type:int(11);size:11;not null;primary_key;column:id;comment:主键ID"`
5 | Uuid string `gorm:"uniqueIndex:uuid;index;not null;size:36;column:uuid;comment:插件id"`
6 | Resources []byte `gorm:"type:mediumblob;serializer:json;column:resources"`
7 | }
8 |
9 | func (c *PluginResources) TableName() string {
10 | return "module_plugin_resources"
11 | }
12 |
13 | func (c *PluginResources) IdValue() int {
14 | return c.ID
15 | }
16 |
--------------------------------------------------------------------------------
/modules/module-plugin/model/plugin_front.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | type PluginInstalledStatus struct {
4 | Installed bool
5 | }
6 |
--------------------------------------------------------------------------------
/modules/module-plugin/service/enum.go:
--------------------------------------------------------------------------------
1 | package service
2 |
3 | const (
4 | pluginGroupOther = "other"
5 |
6 | // statusPluginDisable 插件停用枚举值
7 | statusPluginDisable = 1
8 | // statusPluginEnable 插件启用枚举值
9 | statusPluginEnable = 2
10 |
11 | // pluginTypeFrame 框架插件类型 不可卸载,不可停用,不显示在插件广场
12 | pluginTypeFrame = 0
13 | // pluginTypeCore 核心插件类型 不可卸载,不可停用
14 | pluginTypeCore = 1
15 | // pluginTypeInner 内置插件类型 不可卸载
16 | pluginTypeInner = 2
17 | // pluginTypeNotInner 非内置插件类型
18 | pluginTypeNotInner = 3
19 |
20 | pluginDriverRemote = "remote"
21 | pluginDriverLocal = "local"
22 | )
23 |
--------------------------------------------------------------------------------
/modules/module-plugin/service/error.go:
--------------------------------------------------------------------------------
1 | package service
2 |
3 | import "errors"
4 |
5 | var (
6 | ErrModulePluginNotFound = errors.New("插件不存在")
7 | ErrModulePluginDriverNotFound = errors.New("插件驱动不存在")
8 | ErrModulePluginInstalled = errors.New("插件已安装")
9 | ErrModulePluginHasDisabled = errors.New("插件已停用")
10 | ErrModulePluginCantDisabled = errors.New("插件不可以停用")
11 | ErrModulePluginHasEnabled = errors.New("插件已启用")
12 | )
13 |
--------------------------------------------------------------------------------
/modules/module-plugin/service/init.go:
--------------------------------------------------------------------------------
1 | package service
2 |
3 | import (
4 | "github.com/eolinker/eosc/common/bean"
5 | )
6 |
7 | func init() {
8 | iModulePluginService := newModulePluginService()
9 | iModulePlugin := newModulePlugin()
10 | bean.Injection(&iModulePluginService)
11 | bean.Injection(&iModulePlugin)
12 | iInstalledCache := newIInstalledCache()
13 | iNavigationModulesCache := newNavigationModulesCache()
14 | bean.Injection(&iInstalledCache)
15 | bean.Injection(&iNavigationModulesCache)
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/modules/module-plugin/service/installed_cache.go:
--------------------------------------------------------------------------------
1 | package service
2 |
3 | import (
4 | "fmt"
5 | "github.com/eolinker/apinto-dashboard/cache"
6 | "github.com/eolinker/apinto-dashboard/modules/module-plugin/model"
7 | "time"
8 | )
9 |
10 | type IInstalledCache interface {
11 | cache.IRedisCache[model.PluginInstalledStatus, string]
12 | }
13 |
14 | func installedCacheKey(pluginID string) string {
15 | return fmt.Sprintf("plugin_installed_%s", pluginID)
16 | }
17 |
18 | func newIInstalledCache() IInstalledCache {
19 | return cache.CreateRedisCache[model.PluginInstalledStatus, string](time.Hour, installedCacheKey)
20 | }
21 |
--------------------------------------------------------------------------------
/modules/module-plugin/service/navigation_modules_cache.go:
--------------------------------------------------------------------------------
1 | package service
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/cache"
5 | module_plugin "github.com/eolinker/apinto-dashboard/modules/module-plugin"
6 | "github.com/eolinker/apinto-dashboard/modules/module-plugin/entry"
7 | "time"
8 | )
9 |
10 | func newNavigationModulesCache() module_plugin.INavigationModulesCache {
11 | return cache.CreateRedisCacheNoKey[entry.EnabledModule](10*time.Minute, "navigationModulesCacheKey")
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/modules/module-plugin/store/init.go:
--------------------------------------------------------------------------------
1 | package store
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/store"
5 | "github.com/eolinker/eosc/common/bean"
6 | )
7 |
8 | func init() {
9 | store.RegisterStore(func(db store.IDB) {
10 | modulePlugin := newModulePluginStore(db)
11 | pluginEnable := newModulePluginEnableStore(db)
12 | modulePluginResources := newPluginResourcesStore(db)
13 | pluginPackage := newModulePluginPackageStore(db)
14 |
15 | bean.Injection(&modulePlugin)
16 | bean.Injection(&pluginEnable)
17 | bean.Injection(&modulePluginResources)
18 | bean.Injection(&pluginPackage)
19 |
20 | })
21 | }
22 |
--------------------------------------------------------------------------------
/modules/module-plugin/store/module_plugin_resources.go:
--------------------------------------------------------------------------------
1 | package store
2 |
3 | import (
4 | "context"
5 | "github.com/eolinker/apinto-dashboard/modules/module-plugin/entry"
6 | "github.com/eolinker/apinto-dashboard/store"
7 | )
8 |
9 | type IPluginResources interface {
10 | store.IBaseStore[entry.PluginResources]
11 | GetByUUID(ctx context.Context, uuid string) (*entry.PluginResources, error)
12 | }
13 |
14 | type pluginResources struct {
15 | store.IBaseStore[entry.PluginResources]
16 | }
17 |
18 | func (c *pluginResources) GetByUUID(ctx context.Context, uuid string) (*entry.PluginResources, error) {
19 | return c.IBaseStore.First(ctx, map[string]interface{}{"uuid": uuid})
20 | }
21 |
22 | func newPluginResourcesStore(db store.IDB) IPluginResources {
23 |
24 | return &pluginResources{IBaseStore: store.CreateStore[entry.PluginResources](db)}
25 | }
26 |
--------------------------------------------------------------------------------
/modules/namespace/namespace-entry/namespace.go:
--------------------------------------------------------------------------------
1 | package namespace_entry
2 |
3 | import "time"
4 |
5 | // Namespace 工作空间
6 | type Namespace struct {
7 | Id int `gorm:"type:int(11);size:11;not null;auto_increment;primary_key;column:id;comment:主键ID"`
8 | Name string `gorm:"size:255;not null;column:name;comment:名称"`
9 | CreateTime time.Time `gorm:"type:timestamp;NOT NULL;DEFAULT:CURRENT_TIMESTAMP;column:create_time;comment:创建时间"`
10 | }
11 |
12 | func (Namespace) TableName() string {
13 | return "namespace"
14 | }
15 |
--------------------------------------------------------------------------------
/modules/namespace/namespace-model/namespace.go:
--------------------------------------------------------------------------------
1 | package namespace_model
2 |
3 | import (
4 | "time"
5 | )
6 |
7 | type Namespace struct {
8 | Id int
9 | Name string
10 | CreateTime time.Time
11 | }
12 |
--------------------------------------------------------------------------------
/modules/namespace/namespace-store/init.go:
--------------------------------------------------------------------------------
1 | package namespace_store
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/store"
5 | "github.com/eolinker/eosc/common/bean"
6 | )
7 |
8 | func init() {
9 | store.RegisterStore(func(db store.IDB) {
10 | namespace := newNamespaceStore(db)
11 |
12 | bean.Injection(&namespace)
13 | })
14 | }
15 |
--------------------------------------------------------------------------------
/modules/namespace/service.go:
--------------------------------------------------------------------------------
1 | package namespace
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/modules/namespace/namespace-model"
5 | )
6 |
7 | type INamespaceService interface {
8 | GetByName(namespace string) (*namespace_model.Namespace, error)
9 | GetById(namespaceId int) (*namespace_model.Namespace, error)
10 | GetAll() ([]*namespace_model.Namespace, error)
11 | }
12 |
--------------------------------------------------------------------------------
/modules/navigation/navigation-model/navigation.go:
--------------------------------------------------------------------------------
1 | package navigation_model
2 |
3 | type Navigation struct {
4 | Uuid string `json:"uuid" yaml:"id"`
5 | Name string `json:"-" yaml:"name"`
6 | Title string `json:"title" yaml:"cname"`
7 | Icon string `json:"icon" yaml:"icon"`
8 | Quick bool `json:"quick" yaml:"quick"`
9 | }
10 |
--------------------------------------------------------------------------------
/modules/navigation/navigation-service/init.go:
--------------------------------------------------------------------------------
1 | package navigation_service
2 |
3 | import (
4 | "github.com/eolinker/eosc/common/bean"
5 | )
6 |
7 | func init() {
8 | service := newNavigationService()
9 | bean.Injection(&service)
10 | }
11 |
--------------------------------------------------------------------------------
/modules/navigation/navigation.go:
--------------------------------------------------------------------------------
1 | package navigation
2 |
3 | import (
4 | navigation_model "github.com/eolinker/apinto-dashboard/modules/navigation/navigation-model"
5 | )
6 |
7 | type INavigationService interface {
8 | Info(uuid string) (*navigation_model.Navigation, bool)
9 | List() []*navigation_model.Navigation
10 | }
11 |
12 | type INavigationDataService interface {
13 | GetNavigationData() []*navigation_model.Navigation
14 | }
15 |
--------------------------------------------------------------------------------
/modules/notice/controller/routers.go:
--------------------------------------------------------------------------------
1 | package controller
2 |
3 | import (
4 | apinto_module "github.com/eolinker/apinto-dashboard/module"
5 | "net/http"
6 | )
7 |
8 | func InitRouter() apinto_module.RoutersInfo {
9 | c := newNoticeController()
10 | return []apinto_module.RouterInfo{
11 | {
12 | Method: http.MethodGet,
13 | Path: "/api/channels",
14 | Handler: "notice.getChannelsEnum",
15 | HandlerFunc: []apinto_module.HandlerFunc{c.channels},
16 | },
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/modules/notice/driver.go:
--------------------------------------------------------------------------------
1 | package notice
2 |
3 | import "github.com/eolinker/apinto-dashboard/driver"
4 |
5 | type INoticeChannelDriverManager interface {
6 | driver.IDriverManager[IDriverNoticeChannel]
7 | }
8 |
--------------------------------------------------------------------------------
/modules/notice/dto/notice.go:
--------------------------------------------------------------------------------
1 | package dto
2 |
3 | type NoticeChannel struct {
4 | Uuid string `json:"uuid"`
5 | Title string `json:"title"`
6 | Type int `json:"type"` //1邮箱 2webhook
7 | }
8 |
--------------------------------------------------------------------------------
/modules/notice/notice-service/driver.go:
--------------------------------------------------------------------------------
1 | package notice_service
2 |
3 | import (
4 | driver_manager "github.com/eolinker/apinto-dashboard/driver"
5 | "github.com/eolinker/apinto-dashboard/modules/notice"
6 | )
7 |
8 | type driverNoticeChannel struct {
9 | *driver_manager.DriverManager[notice.IDriverNoticeChannel]
10 | }
11 |
12 | func newNoticeChannelDriverManager() notice.INoticeChannelDriverManager {
13 | return &driverNoticeChannel{DriverManager: driver_manager.CreateDriverManager[notice.IDriverNoticeChannel]()}
14 | }
15 |
16 | // NewNoticeChannelDriverManager
17 | // todo mock 这个文件会报错 Loading input failed: don't know how to mock method of type *ast.IndexExpr 可能是泛型不支持
18 | // 单独提供个方法处理
19 | func NewNoticeChannelDriverManager() notice.INoticeChannelDriverManager {
20 | return &driverNoticeChannel{DriverManager: driver_manager.CreateDriverManager[notice.IDriverNoticeChannel]()}
21 | }
22 |
--------------------------------------------------------------------------------
/modules/notice/notice-service/init.go:
--------------------------------------------------------------------------------
1 | package notice_service
2 |
3 | import "github.com/eolinker/eosc/common/bean"
4 |
5 | func init() {
6 | iNoticeChannelService := newNoticeChannelService()
7 | noticeChannelDriverManager := newNoticeChannelDriverManager()
8 | bean.Injection(&iNoticeChannelService)
9 | bean.Injection(¬iceChannelDriverManager)
10 | }
11 |
--------------------------------------------------------------------------------
/modules/notice/notice-store/init.go:
--------------------------------------------------------------------------------
1 | package notice_store
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/store"
5 | "github.com/eolinker/eosc/common/bean"
6 | )
7 |
8 | func init() {
9 | store.RegisterStore(func(db store.IDB) {
10 | iNoticeChannelStore := newNoticeChannelStore(db)
11 | iNoticeChannelStatStore := newNoticeChannelStatStore(db)
12 | iNoticeChannelVersionStore := newNoticeChannelVersionStore(db)
13 | bean.Injection(&iNoticeChannelStore)
14 | bean.Injection(&iNoticeChannelStatStore)
15 | bean.Injection(&iNoticeChannelVersionStore)
16 | })
17 | }
18 |
--------------------------------------------------------------------------------
/modules/notice/notice.go:
--------------------------------------------------------------------------------
1 | package notice
2 |
3 | import (
4 | "context"
5 | "github.com/eolinker/apinto-dashboard/modules/notice/notice-model"
6 | )
7 |
8 | type INoticeChannelService interface {
9 | CreateNoticeChannel(ctx context.Context, namespaceId, userID int, channel *notice_model.NoticeChannel) error
10 | UpdateNoticeChannel(ctx context.Context, namespaceId, userID int, channel *notice_model.NoticeChannel) error
11 | DeleteNoticeChannel(ctx context.Context, namespaceId, userID int, name string) error
12 | NoticeChannelList(ctx context.Context, namespaceId, typ_ int) ([]*notice_model.NoticeChannel, error)
13 | NoticeChannelByName(ctx context.Context, namespaceId int, name string) (*notice_model.NoticeChannel, error)
14 | InitChannelDriver() error
15 | }
16 |
17 | type IDriverNoticeChannel interface {
18 | SendTo(sends []string, title, msg string) error
19 | }
20 |
--------------------------------------------------------------------------------
/modules/online/online-dto/common_online.go:
--------------------------------------------------------------------------------
1 | package online_dto
2 |
3 | import "github.com/eolinker/apinto-dashboard/enum"
4 |
5 | type OnlineOut struct {
6 | Name string `json:"name"`
7 | Status enum.OnlineStatus `json:"status"`
8 | Env string `json:"env"`
9 | Disable bool `json:"disable"`
10 | Operator string `json:"operator"`
11 | UpdateTime string `json:"update_time"`
12 | }
13 |
14 | type UpdateOnlineStatusInput struct {
15 | ClusterNames []string `json:"cluster_names"`
16 | }
17 |
--------------------------------------------------------------------------------
/modules/online/service.go:
--------------------------------------------------------------------------------
1 | package online
2 |
--------------------------------------------------------------------------------
/modules/openapi/open-api-controller/routers.go:
--------------------------------------------------------------------------------
1 | package open_api_controller
2 |
3 | import (
4 | apinto_module "github.com/eolinker/apinto-dashboard/module"
5 | "net/http"
6 | )
7 |
8 | func initRouter(name string) apinto_module.RoutersInfo {
9 | c := newOpenApiController()
10 | return apinto_module.RoutersInfo{
11 | {
12 | Method: http.MethodGet,
13 | Path: "/api2/apis/import",
14 | Handler: "applications.getImportInfo",
15 | HandlerFunc: []apinto_module.HandlerFunc{c.getImportInfo},
16 | Labels: apinto_module.RouterLabelOpenApi,
17 | },
18 | {
19 | Method: http.MethodPost,
20 | Path: "/api2/apis/import",
21 | Handler: "applications.syncAPI",
22 | HandlerFunc: []apinto_module.HandlerFunc{c.syncAPI},
23 | Labels: apinto_module.RouterLabelOpenApi,
24 | },
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/modules/openapi/openapi-dto/api_openAPI.go:
--------------------------------------------------------------------------------
1 | package openapi_dto
2 |
3 | type SyncImportData struct {
4 | Format string `json:"format"`
5 | Content []byte `json:"content"`
6 | ServiceName string `json:"upstream"`
7 | Server *ImportServerInfo `json:"server,omitempty"`
8 | GroupUUID string `json:"group"`
9 | Label string `json:"label"`
10 | Prefix string `json:"prefix"`
11 | }
12 |
13 | type ImportServerInfo struct {
14 | Scheme string `json:"scheme"`
15 | Nodes []*ImportNodesInfo `json:"nodes"`
16 | }
17 |
18 | type ImportNodesInfo struct {
19 | Url string `json:"url"`
20 | Weight int `json:"weight"`
21 | }
22 |
--------------------------------------------------------------------------------
/modules/openapi/openapi-model/api_openAPI.go:
--------------------------------------------------------------------------------
1 | package openapi_model
2 |
3 | type ApiOpenAPIGroups struct {
4 | Uuid string `json:"uuid"`
5 | Name string `json:"name"`
6 | Children []*ApiOpenAPIGroups `json:"children,omitempty"`
7 | }
8 |
9 | type ApiOpenAPIService struct {
10 | Name string `json:"name"`
11 | Desc string `json:"desc"`
12 | Title string `json:"title"`
13 | }
14 |
15 | type ServiceStaticDriverConf struct {
16 | UseVariable bool `json:"use_variable"`
17 | AddrsVariable string `json:"addrs_variable,omitempty"`
18 | StaticConf []*ServiceStaticConf `json:"static_conf,omitempty"`
19 | }
20 |
21 | type ServiceStaticConf struct {
22 | Addr string `json:"addr"`
23 | Weight int `json:"weight"`
24 | }
25 |
--------------------------------------------------------------------------------
/modules/openapi/openapi-service/init.go:
--------------------------------------------------------------------------------
1 | package openapi_service
2 |
3 | import "github.com/eolinker/eosc/common/bean"
4 |
5 | func init() {
6 | apiOpenAPI := newAPIOpenAPIService()
7 | //openAPI
8 | bean.Injection(&apiOpenAPI)
9 | }
10 |
--------------------------------------------------------------------------------
/modules/openapp/open-app-dto/external_app.go:
--------------------------------------------------------------------------------
1 | package open_app_dto
2 |
3 | type ExternalAppInfoInput struct {
4 | Name string `json:"name"`
5 | Id string `json:"id"`
6 | Desc string `json:"desc"`
7 | }
8 |
9 | type ExternalAppInfoOutput struct {
10 | Name string `json:"name"`
11 | Id string `json:"id"`
12 | Desc string `json:"desc"`
13 | }
14 |
--------------------------------------------------------------------------------
/modules/openapp/open-app-model/external-app.go:
--------------------------------------------------------------------------------
1 | package open_app_model
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/modules/openapp/open-app-entry"
5 | )
6 |
7 | type ExternalAppInfo struct {
8 | *open_app_entry.ExternalApplication
9 | }
10 |
11 | type ExtAppListItem struct {
12 | Id string `json:"id"`
13 | Name string `json:"name"`
14 | Token string `json:"token"`
15 | Tags string `json:"tags"`
16 | Status int `json:"status"`
17 | Operator string `json:"operator"`
18 | UpdateTime string `json:"update_time"`
19 | }
20 |
--------------------------------------------------------------------------------
/modules/openapp/openapp-service/api_import_format.go:
--------------------------------------------------------------------------------
1 | package openapp_service
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/driver"
5 | "github.com/eolinker/apinto-dashboard/modules/openapi"
6 | )
7 |
8 | const (
9 | openAPI3 = "OpenAPI3.0"
10 | swagger2 = "Swagger2.0"
11 | )
12 |
13 | type apiSyncFormatDriver struct {
14 | *driver.DriverManager[openapi.IAPISyncFormatDriver]
15 | }
16 |
17 | func (a *apiSyncFormatDriver) List() []string {
18 | return []string{swagger2, openAPI3}
19 | }
20 |
21 | func newAPISyncFormatManager() openapi.IAPISyncFormatManager {
22 | return &apiSyncFormatDriver{DriverManager: driver.CreateDriverManager[openapi.IAPISyncFormatDriver]()}
23 | }
24 |
--------------------------------------------------------------------------------
/modules/openapp/openapp-service/init.go:
--------------------------------------------------------------------------------
1 | package openapp_service
2 |
3 | import (
4 | driver2 "github.com/eolinker/apinto-dashboard/modules/openapi/driver"
5 | "github.com/eolinker/eosc/common/bean"
6 | )
7 |
8 | func init() {
9 | //同步api文档格式管理器
10 | apiSyncFormatManager := newAPISyncFormatManager()
11 | openAPI3Driver := driver2.CreateOpenAPI3(openAPI3)
12 | openAPI2Driver := driver2.CreateOpenAPI2(swagger2)
13 | apiSyncFormatManager.RegisterDriver(openAPI3, openAPI3Driver)
14 | apiSyncFormatManager.RegisterDriver(swagger2, openAPI2Driver)
15 | bean.Injection(&apiSyncFormatManager)
16 |
17 | externalAPP := newExternalApplicationService()
18 |
19 | bean.Injection(&externalAPP)
20 | }
21 |
--------------------------------------------------------------------------------
/modules/openapp/openapp-store/init.go:
--------------------------------------------------------------------------------
1 | package openapp_store
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/store"
5 | "github.com/eolinker/eosc/common/bean"
6 | )
7 |
8 | func init() {
9 | store.RegisterStore(func(db store.IDB) {
10 | externalAPP := newExternalApplicationStore(db)
11 | bean.Injection(&externalAPP)
12 | })
13 | }
14 |
--------------------------------------------------------------------------------
/modules/plugin/plugin-entry/cluster_plugin_history.go:
--------------------------------------------------------------------------------
1 | package plugin_entry
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/modules/base/history-entry"
5 | "time"
6 | )
7 |
8 | // ClusterPluginHistory 集群绑定的插件变更记录表
9 | type ClusterPluginHistory struct {
10 | Id int
11 | NamespaceId int
12 | ClusterPluginID int
13 | OldValue ClusterPluginHistoryValue
14 | NewValue ClusterPluginHistoryValue
15 | OptType history_entry.OptType
16 | Operator int
17 | OptTime time.Time
18 | }
19 |
20 | type ClusterPluginHistoryValue struct {
21 | PluginName string `json:"plugin_name"`
22 | Status int `json:"status"`
23 | Config string `json:"config"`
24 | }
25 |
--------------------------------------------------------------------------------
/modules/plugin/plugin-entry/cluster_plugin_runtime.go:
--------------------------------------------------------------------------------
1 | package plugin_entry
2 |
3 | import "time"
4 |
5 | // ClusterPluginRuntime 集群当前插件配置的版本
6 | type ClusterPluginRuntime struct {
7 | Id int `json:"id"`
8 | ClusterId int `json:"cluster_id"`
9 | NamespaceId int `json:"namespace_id"`
10 | VersionId int `json:"version_id"`
11 | IsOnline bool `json:"is_online"`
12 | Operator int `json:"operator"`
13 | CreateTime time.Time `json:"create_time"`
14 | UpdateTime time.Time `json:"update_time"`
15 | }
16 |
--------------------------------------------------------------------------------
/modules/plugin/plugin-entry/plugin_history.go:
--------------------------------------------------------------------------------
1 | package plugin_entry
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/modules/base/history-entry"
5 | "time"
6 | )
7 |
8 | type PluginHistory struct {
9 | Id int
10 | PluginID int
11 | NamespaceId int
12 | OldValue PluginHistoryInfo
13 | NewValue PluginHistoryInfo
14 | OptType history_entry.OptType //1新增 2修改 3删除
15 | OptTime time.Time
16 | Operator int
17 | }
18 |
19 | type PluginHistoryInfo struct {
20 | Plugin Plugin `json:"plugin"`
21 | }
22 |
--------------------------------------------------------------------------------
/modules/plugin/plugin-service/extender_cache.go:
--------------------------------------------------------------------------------
1 | package plugin_service
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/cache"
5 | "github.com/eolinker/apinto-dashboard/modules/plugin/plugin-model"
6 | "time"
7 | )
8 |
9 | type IExtenderCache interface {
10 | cache.IRedisCacheNoKey[plugin_model.ExtenderInfo]
11 | }
12 |
13 | func newIExtenderCache() IExtenderCache {
14 | return cache.CreateRedisCacheNoKey[plugin_model.ExtenderInfo](time.Minute*5, "extender")
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/modules/plugin/plugin-service/init.go:
--------------------------------------------------------------------------------
1 | package plugin_service
2 |
3 | import (
4 | "github.com/eolinker/eosc/common/bean"
5 | )
6 |
7 | func init() {
8 | pluginServiceInfo := newPluginService()
9 | clusterPluginServiceInfo := newClusterPluginService()
10 | bean.Injection(&pluginServiceInfo)
11 | bean.Injection(&clusterPluginServiceInfo)
12 | iExtenderCache := newIExtenderCache()
13 | bean.Injection(&iExtenderCache)
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/modules/plugin/plugin_timer/init.go:
--------------------------------------------------------------------------------
1 | package plugin_timer
2 |
3 | import (
4 | "time"
5 | )
6 |
7 | func ExtenderTimer() {
8 |
9 | iExtender := newExtender()
10 |
11 | //第一次启动就去更新扩展ID插件
12 | go iExtender.UpdateExtender()
13 | secondTick := time.Tick(time.Second)
14 | for t := range secondTick {
15 | if t.Second() == 0 { //1分钟执行一次
16 | go iExtender.UpdateExtender()
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/modules/plugin_template/plugin-template-entry/plugin_template_history.go:
--------------------------------------------------------------------------------
1 | package plugin_template_entry
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/modules/base/history-entry"
5 | "time"
6 | )
7 |
8 | type PluginTemplateHistory struct {
9 | Id int
10 | PluginTemplateID int
11 | NamespaceId int
12 | OldValue PluginTemplateHistoryInfo
13 | NewValue PluginTemplateHistoryInfo
14 | OptType history_entry.OptType //1新增 2修改 3删除
15 | OptTime time.Time
16 | Operator int
17 | }
18 |
19 | type PluginTemplateHistoryInfo struct {
20 | PluginTemplate PluginTemplate `json:"plugin_template"`
21 | Config PluginTemplateVersionConfig `json:"config"`
22 | }
23 |
--------------------------------------------------------------------------------
/modules/plugin_template/plugin-template-entry/plugin_template_runtime.go:
--------------------------------------------------------------------------------
1 | package plugin_template_entry
2 |
3 | import "time"
4 |
5 | type PluginTemplateRuntime struct {
6 | Id int
7 | NamespaceId int
8 | PluginTemplateID int
9 | ClusterID int
10 | VersionID int
11 | IsOnline bool
12 | Disable bool
13 | Operator int
14 | CreateTime time.Time
15 | UpdateTime time.Time
16 | }
17 |
--------------------------------------------------------------------------------
/modules/plugin_template/plugin-template-entry/plugin_template_stat.go:
--------------------------------------------------------------------------------
1 | package plugin_template_entry
2 |
3 | type PluginTemplateStat struct {
4 | PluginTemplateId int
5 | VersionID int
6 | }
7 |
--------------------------------------------------------------------------------
/modules/plugin_template/plugin-template-entry/plugin_template_version.go:
--------------------------------------------------------------------------------
1 | package plugin_template_entry
2 |
3 | import "time"
4 |
5 | type PluginTemplateVersion struct {
6 | Id int
7 | PluginTemplateId int
8 | NamespaceID int
9 | PluginTemplateVersionConfig
10 | Operator int
11 | CreateTime time.Time
12 | }
13 |
14 | func (p *PluginTemplateVersion) SetVersionId(id int) {
15 | p.Id = id
16 | }
17 |
18 | type PluginTemplateVersionConfig struct {
19 | Plugins []*PluginTemplateVersionConfigDetail `json:"plugins"`
20 | }
21 |
22 | type PluginTemplateVersionConfigDetail struct {
23 | UUID string `json:"uuid,omitempty"`
24 | Name string `json:"name,omitempty"`
25 | Config string `json:"config,omitempty"`
26 | Disable bool `json:"disable,omitempty"`
27 | }
28 |
--------------------------------------------------------------------------------
/modules/plugin_template/plugin-template-entry/publish_history.go:
--------------------------------------------------------------------------------
1 | package plugin_template_entry
2 |
3 | import "time"
4 |
5 | type PluginTemplatePublishHistory struct {
6 | Id int
7 | VersionName string
8 | ClusterId int
9 | NamespaceId int
10 | Desc string
11 | VersionId int
12 | Target int
13 | PluginTemplateVersionConfig
14 | OptType int
15 | Operator int
16 | OptTime time.Time
17 | }
18 |
--------------------------------------------------------------------------------
/modules/plugin_template/plugin-template-service/init.go:
--------------------------------------------------------------------------------
1 | package plugin_template_service
2 |
3 | import (
4 | "github.com/eolinker/eosc/common/bean"
5 | )
6 |
7 | func init() {
8 |
9 | clusterTemplatePlugin := newPluginTemplateService()
10 |
11 | bean.Injection(&clusterTemplatePlugin)
12 | }
13 |
--------------------------------------------------------------------------------
/modules/plugin_template/plugin-template-store/init.go:
--------------------------------------------------------------------------------
1 | package plugin_template_store
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/store"
5 | "github.com/eolinker/eosc/common/bean"
6 | )
7 |
8 | func init() {
9 | store.RegisterStore(func(db store.IDB) {
10 | historyStore := newPluginTemplateHistoryStore(db)
11 | templateStore := newPluginTemplateStore(db)
12 | statStore := newPluginTemplateStatStore(db)
13 | versionStore := newPluginTemplateVersionStore(db)
14 | publishHistory := newPluginTemplatePublishHistoryStore(db)
15 |
16 | bean.Injection(&historyStore)
17 | bean.Injection(&templateStore)
18 | bean.Injection(&statStore)
19 | bean.Injection(&versionStore)
20 | bean.Injection(&publishHistory)
21 | })
22 | }
23 |
--------------------------------------------------------------------------------
/modules/random/random-service/init.go:
--------------------------------------------------------------------------------
1 | package random_service
2 |
3 | import "github.com/eolinker/eosc/common/bean"
4 |
5 | func init() {
6 | random := newRandomService()
7 |
8 | bean.Injection(&random)
9 | }
10 |
--------------------------------------------------------------------------------
/modules/random/random-service/random.go:
--------------------------------------------------------------------------------
1 | package random_service
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/common"
5 | "github.com/eolinker/apinto-dashboard/modules/random"
6 | )
7 |
8 | type randomService struct {
9 | }
10 |
11 | func newRandomService() random.IRandomService {
12 | return &randomService{}
13 | }
14 |
15 | func (randomService) RandomStr(ruleName string) string {
16 | // todo 这里需要换成通过注册取代来实现
17 | switch ruleName {
18 | case "application":
19 | return common.RandStr(16)
20 | case "external-app":
21 | return common.RandStr(16)
22 | case "external-app-token": //外部应用长度32的token
23 | return common.RandStr(32)
24 | case "password":
25 | return "12345678"
26 | return common.RandStr(8)
27 | default:
28 | return ""
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/modules/random/random.go:
--------------------------------------------------------------------------------
1 | package random
2 |
3 | type IRandomService interface {
4 | RandomStr(ruleName string) string
5 | }
6 |
--------------------------------------------------------------------------------
/modules/remote_storage/entry/remote_key_object.go:
--------------------------------------------------------------------------------
1 | package entry
2 |
3 | import "gorm.io/gorm"
4 |
5 | type RemoteKeyObject struct {
6 | Module string `gorm:"uniqueIndex:module_key;index;not null;size:255;column:module;comment:模块名"`
7 | Key string `gorm:"uniqueIndex:module_key;not null;size:32;column:key"` //TODO key要多长
8 | Object interface{} `gorm:"type:text;serializer:json;column:object"`
9 | gorm.Model
10 | }
11 |
12 | func (c *RemoteKeyObject) TableName() string {
13 | return "remote_storage"
14 | }
15 |
16 | func (c *RemoteKeyObject) IdValue() int {
17 | return int(c.ID)
18 | }
19 |
--------------------------------------------------------------------------------
/modules/remote_storage/model/remote_storage.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | import "time"
4 |
5 | type RemoteStorage struct {
6 | Module string
7 | Key string
8 | Object interface{}
9 | UpdateAt time.Time
10 | CreateAt time.Time
11 | }
12 |
--------------------------------------------------------------------------------
/modules/remote_storage/remote_storage.go:
--------------------------------------------------------------------------------
1 | package remote_storage
2 |
3 | import "github.com/eolinker/apinto-dashboard/modules/remote_storage/model"
4 |
5 | type IRemoteStorageService interface {
6 | Get(module, key string) (*model.RemoteStorage, error)
7 | Save(module, key string, object interface{}) error
8 | }
9 |
--------------------------------------------------------------------------------
/modules/remote_storage/service/init.go:
--------------------------------------------------------------------------------
1 | package service
2 |
3 | import "github.com/eolinker/eosc/common/bean"
4 |
5 | func init() {
6 | remoteStorage := newRemoteStorageService()
7 | bean.Injection(&remoteStorage)
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/modules/remote_storage/store/init.go:
--------------------------------------------------------------------------------
1 | package store
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/store"
5 | "github.com/eolinker/eosc/common/bean"
6 | )
7 |
8 | func init() {
9 | store.RegisterStore(func(db store.IDB) {
10 | remoteStorageStore := newRemoteStorageStore(db)
11 | bean.Injection(&remoteStorageStore)
12 | })
13 | }
14 |
--------------------------------------------------------------------------------
/modules/strategy/config/content-type.yml:
--------------------------------------------------------------------------------
1 | -
2 | content_type: application/json
3 | body: |-
4 | {
5 | "msg":"很抱歉,$api 暂停服务,请稍候再试!"
6 | }
7 | -
8 | content_type: application/xml
9 | body: |-
10 |
11 | 很抱歉,$api 暂停服务,请稍候再试!
12 | -
13 | content_type: text/html
14 | body: " 很抱歉,$api 暂停服务,请稍候再试!
"
--------------------------------------------------------------------------------
/modules/strategy/strategy-controller/stragety-traffic.go:
--------------------------------------------------------------------------------
1 | package strategy_controller
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/modules/strategy/config"
5 | strategy_entry "github.com/eolinker/apinto-dashboard/modules/strategy/strategy-entry"
6 | "github.com/eolinker/apinto-dashboard/modules/strategy/strategy-service"
7 | "github.com/eolinker/apinto-dashboard/modules/strategy/strategy-service/strategy-handler"
8 | )
9 |
10 | func newStrategyTrafficController() *strategyController[strategy_entry.StrategyTrafficLimitConfig, strategy_entry.StrategyTrafficLimitConfig] {
11 | strategyService := strategy_service.NewStrategyService(strategy_handler.NewStrategyTrafficHandler("strategy-limiting"), config.StrategyTrafficRuntimeKind)
12 |
13 | c := newStrategyController(strategyService)
14 |
15 | return c
16 | }
17 |
--------------------------------------------------------------------------------
/modules/strategy/strategy-controller/strategy-cache.go:
--------------------------------------------------------------------------------
1 | package strategy_controller
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/modules/strategy/config"
5 | strategy_entry "github.com/eolinker/apinto-dashboard/modules/strategy/strategy-entry"
6 | "github.com/eolinker/apinto-dashboard/modules/strategy/strategy-service"
7 | "github.com/eolinker/apinto-dashboard/modules/strategy/strategy-service/strategy-handler"
8 | )
9 |
10 | func newStrategyCacheController() *strategyController[strategy_entry.StrategyCacheConfig, strategy_entry.StrategyCacheConfig] {
11 | strategyService := strategy_service.NewStrategyService(strategy_handler.NewStrategyCacheHandler("strategy-cache"), config.StrategyCacheRuntimeKind)
12 |
13 | c := newStrategyController(strategyService)
14 | return c
15 | }
16 |
--------------------------------------------------------------------------------
/modules/strategy/strategy-controller/strategy-fuse.go:
--------------------------------------------------------------------------------
1 | package strategy_controller
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/modules/strategy/config"
5 | strategy_entry "github.com/eolinker/apinto-dashboard/modules/strategy/strategy-entry"
6 | "github.com/eolinker/apinto-dashboard/modules/strategy/strategy-service"
7 | "github.com/eolinker/apinto-dashboard/modules/strategy/strategy-service/strategy-handler"
8 | )
9 |
10 | func newStrategyFuseController() *strategyController[strategy_entry.StrategyFuseConfig, strategy_entry.StrategyFuseConfig] {
11 | strategyService := strategy_service.NewStrategyService(strategy_handler.NewStrategyFuseHandler("strategy-fuse"), config.StrategyFuseRuntimeKind)
12 |
13 | c := newStrategyController(strategyService)
14 | return c
15 | }
16 |
--------------------------------------------------------------------------------
/modules/strategy/strategy-controller/strategy-grey.go:
--------------------------------------------------------------------------------
1 | package strategy_controller
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/modules/strategy/config"
5 | strategy_entry "github.com/eolinker/apinto-dashboard/modules/strategy/strategy-entry"
6 | "github.com/eolinker/apinto-dashboard/modules/strategy/strategy-service"
7 | "github.com/eolinker/apinto-dashboard/modules/strategy/strategy-service/strategy-handler"
8 | )
9 |
10 | func newStrategyGreyController() *strategyController[strategy_entry.StrategyGreyConfig, strategy_entry.StrategyGreyConfig] {
11 | strategyService := strategy_service.NewStrategyService(strategy_handler.NewStrategyGreyHandler("strategy-grey"), config.StrategyGreyRuntimeKind)
12 |
13 | c := newStrategyController(strategyService)
14 | return c
15 | }
16 |
--------------------------------------------------------------------------------
/modules/strategy/strategy-controller/strategy-visit.go:
--------------------------------------------------------------------------------
1 | package strategy_controller
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/modules/strategy/config"
5 | strategy_entry "github.com/eolinker/apinto-dashboard/modules/strategy/strategy-entry"
6 | strategy_model "github.com/eolinker/apinto-dashboard/modules/strategy/strategy-model"
7 | "github.com/eolinker/apinto-dashboard/modules/strategy/strategy-service"
8 | "github.com/eolinker/apinto-dashboard/modules/strategy/strategy-service/strategy-handler"
9 | )
10 |
11 | func newStrategyVisitController() *strategyController[strategy_entry.StrategyVisitConfig, strategy_model.VisitInfoOutputConf] {
12 | strategyService := strategy_service.NewStrategyService(strategy_handler.NewStrategyVisitHandler("strategy-visit"), config.StrategyVisitRuntimeKind)
13 |
14 | c := newStrategyController(strategyService)
15 | return c
16 | }
17 |
--------------------------------------------------------------------------------
/modules/strategy/strategy-entry/strategy_history.go:
--------------------------------------------------------------------------------
1 | package strategy_entry
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/modules/base/history-entry"
5 | "time"
6 | )
7 |
8 | type StrategyHistoryInfo struct {
9 | Strategy Strategy `json:"strategy,omitempty"`
10 | Config StrategyConfigInfo `json:"config"`
11 | }
12 |
13 | type StrategyHistory struct {
14 | Id int
15 | StrategyId int
16 | NamespaceId int
17 | OldValue StrategyHistoryInfo
18 | NewValue StrategyHistoryInfo
19 | OptType history_entry.OptType //1新增 2修改 3删除
20 | OptTime time.Time
21 | Operator int
22 | }
23 |
--------------------------------------------------------------------------------
/modules/strategy/strategy-entry/strategy_publish_history.go:
--------------------------------------------------------------------------------
1 | package strategy_entry
2 |
3 | import "time"
4 |
5 | type StrategyPublishHistory struct {
6 | Id int
7 | VersionName string
8 | ClusterId int
9 | NamespaceId int
10 | Desc string
11 | VersionId int
12 | Publish []*StrategyPublishConfigInfo //此次发布的数据
13 | OptType int
14 | Operator int
15 | CreateTime time.Time
16 | }
17 |
18 | //type StrategyPublishHistoryInfo struct {
19 | // Publish []*StrategyPublishConfigInfo `json:"publish"`
20 | //}
21 |
--------------------------------------------------------------------------------
/modules/strategy/strategy-entry/strategy_runtime.go:
--------------------------------------------------------------------------------
1 | package strategy_entry
2 |
3 | import "time"
4 |
5 | type StrategyRuntime struct {
6 | Id int `json:"id"`
7 | ClusterId int `json:"cluster_id"`
8 | NamespaceId int `json:"namespace_id"`
9 | VersionId int `json:"version_id"`
10 | IsOnline bool `json:"is_online"`
11 | Operator int `json:"operator"`
12 | CreateTime time.Time `json:"create_time"`
13 | UpdateTime time.Time `json:"update_time"`
14 | }
15 |
--------------------------------------------------------------------------------
/modules/strategy/strategy-entry/strategy_stat.go:
--------------------------------------------------------------------------------
1 | package strategy_entry
2 |
3 | type StrategyStat struct {
4 | StrategyId int
5 | VersionId int
6 | }
7 |
--------------------------------------------------------------------------------
/modules/strategy/strategy-service/filters.go:
--------------------------------------------------------------------------------
1 | package strategy_service
2 |
3 | type IFilterHandler interface {
4 | }
5 |
--------------------------------------------------------------------------------
/modules/strategy/strategy-service/init.go:
--------------------------------------------------------------------------------
1 | package strategy_service
2 |
3 | import "github.com/eolinker/eosc/common/bean"
4 |
5 | func init() {
6 | commonStrategy := newStrategyCommonService()
7 |
8 | bean.Injection(&commonStrategy)
9 | }
10 |
--------------------------------------------------------------------------------
/modules/strategy/strategy-store/init.go:
--------------------------------------------------------------------------------
1 | package strategy_store
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/store"
5 | "github.com/eolinker/eosc/common/bean"
6 | )
7 |
8 | func init() {
9 | store.RegisterStore(func(db store.IDB) {
10 | strategy := newStrategyStore(db)
11 | strategyStat := newStrategyStatStore(db)
12 |
13 | strategyVersion := newStrategyVersionStore(db)
14 |
15 | strategyHistory := newStrategyHistoryStore(db)
16 | bean.Injection(&strategy)
17 | bean.Injection(&strategyStat)
18 |
19 | bean.Injection(&strategyVersion)
20 |
21 | bean.Injection(&strategyHistory)
22 | })
23 | }
24 |
--------------------------------------------------------------------------------
/modules/system/service/init.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
3 | * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
4 | * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
5 | * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
6 | * Vestibulum commodo. Ut rhoncus gravida arcu.
7 | */
8 |
9 | package service
10 |
11 | import (
12 | "github.com/eolinker/eosc/common/bean"
13 | )
14 |
15 | func init() {
16 |
17 | iml := newDataServiceIml()
18 | bean.Injection(&iml)
19 | }
20 |
--------------------------------------------------------------------------------
/modules/system/system-entry/system_info.go:
--------------------------------------------------------------------------------
1 | package system_entry
2 |
3 | // SystemInfo 系统信息表
4 | type SystemInfo struct {
5 | Id int `gorm:"type:int(11);size:11;not null;auto_increment;primary_key;column:id;comment:主键ID"`
6 | Key string `gorm:"size:20;not null;column:key;uniqueIndex:unique_key;comment:健"`
7 | Value []byte `gorm:"type:text;not null;column:value;comment:值"`
8 | }
9 |
10 | func (*SystemInfo) TableName() string {
11 | return "system_info"
12 | }
13 |
14 | func (c *SystemInfo) IdValue() int {
15 | return c.Id
16 | }
17 |
--------------------------------------------------------------------------------
/modules/system/system-store/init.go:
--------------------------------------------------------------------------------
1 | package system_store
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/store"
5 | "github.com/eolinker/eosc/common/bean"
6 | )
7 |
8 | func init() {
9 | store.RegisterStore(func(db store.IDB) {
10 | systemInfo := newSystemInfoStore(db)
11 | bean.Injection(&systemInfo)
12 |
13 | })
14 | }
15 |
--------------------------------------------------------------------------------
/modules/system/system.go:
--------------------------------------------------------------------------------
1 | package system
2 |
3 | type ISystemConfigService[T any] interface {
4 | Get() (*T, error)
5 | Set(t *T) error
6 | }
7 | type ISystemConfigServiceSimple interface {
8 | Get() ([]byte, error)
9 | Set(v []byte) error
10 | }
11 | type ISystemConfigDataService interface {
12 | Get(key string) ([]byte, error)
13 | Set(key string, v []byte) error
14 | }
15 |
--------------------------------------------------------------------------------
/modules/user/user-dto/access.go:
--------------------------------------------------------------------------------
1 | package user_dto
2 |
3 | type UserAccess struct {
4 | Name string `json:"name"`
5 | Access string `json:"access"`
6 | }
7 |
--------------------------------------------------------------------------------
/modules/user/user-model/session.go:
--------------------------------------------------------------------------------
1 | package user_model
2 |
3 | type Session struct {
4 | Jwt string
5 | RJwt string
6 | }
7 |
--------------------------------------------------------------------------------
/modules/user/user-service/init.go:
--------------------------------------------------------------------------------
1 | package service
2 |
3 | import (
4 | "github.com/eolinker/eosc/common/bean"
5 | )
6 |
7 | func init() {
8 | infoService := newUserInfoService()
9 | bean.Injection(&infoService)
10 | userInfo := newUserInfoIdCache()
11 | userNameInfo := newUserInfoNameCache()
12 | session := newSessionCache()
13 | bean.Injection(&userInfo)
14 | bean.Injection(&userNameInfo)
15 | bean.Injection(&session)
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/modules/user/user-service/session.go:
--------------------------------------------------------------------------------
1 | package service
2 |
3 | import (
4 | "fmt"
5 | "time"
6 |
7 | "github.com/eolinker/apinto-dashboard/modules/user"
8 | user_model "github.com/eolinker/apinto-dashboard/modules/user/user-model"
9 |
10 | "github.com/eolinker/apinto-dashboard/cache"
11 | )
12 |
13 | func sessionCacheKey(session string) string {
14 | return fmt.Sprintf("session:%s", session)
15 | }
16 |
17 | func newSessionCache() user.ISessionCache {
18 | return cache.CreateRedisCache[user_model.Session](time.Hour*24*7, sessionCacheKey, "apinto", "session")
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/modules/user/user-store/init.go:
--------------------------------------------------------------------------------
1 | package user_store
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/store"
5 | "github.com/eolinker/eosc/common/bean"
6 | )
7 |
8 | func init() {
9 | store.RegisterStore(func(db store.IDB) {
10 | userInfo := newUserInfoStore(db)
11 |
12 | bean.Injection(&userInfo)
13 |
14 | })
15 | }
16 |
--------------------------------------------------------------------------------
/modules/variable/variable-dto/global_variable.go:
--------------------------------------------------------------------------------
1 | package variable_dto
2 |
3 | import "github.com/eolinker/apinto-dashboard/enum"
4 |
5 | type GlobalVariableListItem struct {
6 | Key string `json:"key"`
7 | Status enum.VariableUsageStatus `json:"status"`
8 | Description string `json:"description"`
9 | Operator string `json:"operator"`
10 | CreateTime string `json:"create_time"`
11 | }
12 |
13 | type GlobalVariableDetailsItem struct {
14 | ClusterName string `json:"cluster_name"`
15 | Environment string `json:"environment"`
16 | Value string `json:"value"`
17 | Status enum.PublishType `json:"publish_status"`
18 | }
19 |
20 | type GlobalVariableInput struct {
21 | Key string `json:"key"`
22 | Desc string `json:"desc"`
23 | }
24 |
--------------------------------------------------------------------------------
/modules/variable/variable-entry/variable_history.go:
--------------------------------------------------------------------------------
1 | package variable_entry
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/modules/base/history-entry"
5 | "time"
6 | )
7 |
8 | // VariableHistory 集群绑定的环境变量变更记录表
9 | type VariableHistory struct {
10 | Id int
11 | ClusterId int
12 | NamespaceId int
13 | VariableId int
14 | OldValue VariableValue
15 | NewValue VariableValue
16 | OptType history_entry.OptType
17 | Operator int
18 | OptTime time.Time
19 | }
20 |
21 | type VariableValue struct {
22 | Key string `json:"key,omitempty"`
23 | Value string `json:"value,omitempty"`
24 | }
25 |
--------------------------------------------------------------------------------
/modules/variable/variable-entry/variable_publish_history.go:
--------------------------------------------------------------------------------
1 | package variable_entry
2 |
3 | import "time"
4 |
5 | type VariablePublishHistory struct {
6 | Id int
7 | VersionName string
8 | ClusterId int
9 | NamespaceId int
10 | Desc string
11 | VersionId int
12 | VariablePublishHistoryInfo
13 | OptType int
14 | Operator int
15 | OptTime time.Time
16 | }
17 |
18 | type VariablePublishHistoryInfo struct {
19 | VariableToPublish []*VariableToPublish `json:"variable_to_publish"` //发布记录
20 | }
21 |
--------------------------------------------------------------------------------
/modules/variable/variable-entry/variable_runtime.go:
--------------------------------------------------------------------------------
1 | package variable_entry
2 |
3 | import "time"
4 |
5 | // VariableRuntime 集群当前版本
6 | type VariableRuntime struct {
7 | Id int `json:"id"`
8 | ClusterId int `json:"cluster_id"`
9 | NamespaceId int `json:"namespace_id"`
10 | VersionId int `json:"version_id"`
11 | IsOnline bool `json:"is_online"`
12 | Operator int `json:"operator"`
13 | CreateTime time.Time `json:"create_time"`
14 | UpdateTime time.Time `json:"update_time"`
15 | }
16 |
--------------------------------------------------------------------------------
/modules/variable/variable-model/global_variable.go:
--------------------------------------------------------------------------------
1 | package variable_model
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/modules/variable/variable-entry"
5 | )
6 |
7 | type GlobalVariable struct {
8 | *variable_entry.Variables
9 | }
10 |
11 | type GlobalVariableListItem struct {
12 | *variable_entry.Variables
13 | Status int
14 | OperatorStr string
15 | }
16 |
17 | type GlobalVariableDetails struct {
18 | *variable_entry.ClusterVariable
19 | Status int
20 | ClusterName string
21 | Environment string
22 | }
23 |
--------------------------------------------------------------------------------
/modules/variable/variable-service/init.go:
--------------------------------------------------------------------------------
1 | package variable_service
2 |
3 | import "github.com/eolinker/eosc/common/bean"
4 |
5 | func init() {
6 | globalVariable := newGlobalVariableService()
7 |
8 | bean.Injection(&globalVariable)
9 |
10 | clusterVariable := newClusterVariableService()
11 |
12 | bean.Injection(&clusterVariable)
13 | }
14 |
--------------------------------------------------------------------------------
/modules/variable/variable-store/init.go:
--------------------------------------------------------------------------------
1 | package variable_store
2 |
3 | import (
4 | "github.com/eolinker/apinto-dashboard/store"
5 | "github.com/eolinker/eosc/common/bean"
6 | )
7 |
8 | func init() {
9 | store.RegisterStore(func(db store.IDB) {
10 | globalVariable := newGlobalVariableStore(db)
11 | clusterVariable := newClusterVariableStore(db)
12 |
13 | variableHistory := newVariableHistoryStore(db)
14 | variablePublishVersion := newVariablePublishVersionStore(db)
15 | variableRuntime := newVariableRuntimeStore(db)
16 | variablePublishHistory := newVariablePublishHistoryStore(db)
17 | bean.Injection(&variableHistory)
18 | bean.Injection(&variablePublishVersion)
19 | bean.Injection(&variableRuntime)
20 | bean.Injection(&variablePublishHistory)
21 | bean.Injection(&clusterVariable)
22 | bean.Injection(&globalVariable)
23 | })
24 | }
25 |
--------------------------------------------------------------------------------
/plugin/go-plugin/example/.gitignore:
--------------------------------------------------------------------------------
1 | /example
2 | /example.exe
3 |
--------------------------------------------------------------------------------
/plugin/go-plugin/example/config.yml:
--------------------------------------------------------------------------------
1 | port: 8080
2 | mysql:
3 | user_name: "apinto"
4 | password: "Apinto123"
5 | ip: "47.106.231.246"
6 | port: 30006
7 | db: "apserver"
8 | redis:
9 | user_name: ""
10 | password: "I*IR1VGJ8tT5Y0)G"
11 | addr:
12 | - 172.18.166.219:7201
13 | - 172.18.166.219:7202
14 | - 172.18.166.219:7203
15 | - 172.18.166.219:7204
16 | - 172.18.166.219:7205
17 | - 172.18.166.219:7206
18 | error_log:
19 | dir: work/logs # 日志放置目录, 支持相对路径和绝对路径
20 | file_name: error.log # 错误日志文件名
21 | log_level: debug # 错误日志等级,可选:panic,fatal,error,warning,info,debug,trace 不填或者非法则为info
22 | log_expire: 7d # 错误日志过期时间,默认单位为天,d|天,h|小时, 不合法配置默认为7d
23 | log_period: day # 错误日志切割周期,仅支持day、hour
24 |
--------------------------------------------------------------------------------
/plugin/go-plugin/example/plugin/.gitignore:
--------------------------------------------------------------------------------
1 | /plugin
2 | /plugin.exe
3 |
--------------------------------------------------------------------------------
/plugin/go-plugin/plugin/config.go:
--------------------------------------------------------------------------------
1 | package plugin
2 |
3 | import (
4 | "encoding/json"
5 | "github.com/eolinker/apinto-dashboard/config"
6 | "os"
7 | )
8 |
9 | func init() {
10 | initConfig()
11 | initLogger()
12 | }
13 | func initConfig() {
14 |
15 | if os.Getenv("ApintoDashboardConfig") != "true" {
16 | config.ReadConfig()
17 | return
18 | }
19 | c := new(config.Config)
20 | err := json.NewDecoder(os.Stdin).Decode(c)
21 | if err != nil {
22 | logger.Error("read config", err)
23 | return
24 | }
25 | config.SetConfig(c)
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/plugin/go-plugin/plugin/response.go:
--------------------------------------------------------------------------------
1 | package plugin
2 |
3 | import (
4 | "bytes"
5 | "net/http"
6 | )
7 |
8 | type responseWriter struct {
9 | buf *bytes.Buffer
10 | header http.Header
11 | status int
12 | }
13 |
14 | func newResponseWriter() *responseWriter {
15 | return &responseWriter{
16 | header: make(http.Header),
17 | buf: bytes.NewBuffer(nil),
18 | }
19 | }
20 |
21 | func (r *responseWriter) Header() http.Header {
22 | return r.header
23 | }
24 |
25 | func (r *responseWriter) Write(data []byte) (int, error) {
26 | return r.buf.Write(data)
27 | }
28 |
29 | func (r *responseWriter) WriteHeader(statusCode int) {
30 | r.status = statusCode
31 | }
32 |
--------------------------------------------------------------------------------
/plugin/go-plugin/plugin/server_keys.go:
--------------------------------------------------------------------------------
1 | package plugin
2 |
3 | import (
4 | "context"
5 | "github.com/gin-gonic/gin"
6 | "os"
7 | )
8 |
9 | type ginKeysKey struct{}
10 |
11 | var (
12 | GinKeys = &ginKeysKey{}
13 | )
14 |
15 | func Engine() *gin.Engine {
16 | gin.SetMode(gin.ReleaseMode)
17 | engine := gin.New()
18 | engine.Use(gin.LoggerWithWriter(os.Stderr))
19 | engine.Use(KeyForGin)
20 | engine.ContextWithFallback = true
21 | return engine
22 | }
23 | func widthKey(ctx context.Context, keys map[string]interface{}) context.Context {
24 | ctx = context.WithValue(ctx, GinKeys, keys)
25 | return ctx
26 | }
27 | func KeyForGin(ginCtx *gin.Context) {
28 | value := ginCtx.Value(GinKeys)
29 | if value != nil {
30 | keys := value.(map[string]interface{})
31 | if keys == nil {
32 | return
33 | }
34 | for k, v := range keys {
35 | ginCtx.Set(k, v)
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/plugin/go-plugin/proto/gen.go:
--------------------------------------------------------------------------------
1 | //go:generate protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative plugin.proto
2 |
3 | package proto
4 |
--------------------------------------------------------------------------------
/plugin/go-plugin/shared/config.go:
--------------------------------------------------------------------------------
1 | package shared
2 |
3 | import "github.com/hashicorp/go-plugin"
4 |
5 | var HandshakeConfig = plugin.HandshakeConfig{
6 | ProtocolVersion: 1,
7 | MagicCookieKey: "HTTP_HANDLER_PLUGIN",
8 | MagicCookieValue: "Apinto_Dashboard_Plugin",
9 | }
10 |
--------------------------------------------------------------------------------
/plugin/go-plugin/shared/handler.go:
--------------------------------------------------------------------------------
1 | package shared
2 |
3 | import (
4 | module "github.com/eolinker/apinto-dashboard/module"
5 | "net/http"
6 | )
7 |
8 | const PluginHandlerName = "apinto-dashboard"
9 |
10 | type HttpHandler interface {
11 | ServeHTTP(w http.ResponseWriter, r *http.Request)
12 | }
13 |
14 | type MiddlewareHandler interface {
15 | OnHttpRequest(r *module.MiddlewareRequest) module.MiddlewareResponseWriter
16 | onHttpResponse(r *module.MiddlewareRequest) module.MiddlewareResponseWriter
17 | }
18 |
--------------------------------------------------------------------------------
/plugin/local/cmd_unix.go:
--------------------------------------------------------------------------------
1 | //go:build !windows
2 |
3 | package local
4 |
5 | import (
6 | "path/filepath"
7 | )
8 |
9 | var PluginDir, _ = filepath.Abs("local")
10 |
11 | func cmdPath(name string) string {
12 | return filepath.Join(PluginDir, name)
13 | }
14 |
--------------------------------------------------------------------------------
/plugin/local/cmd_win.go:
--------------------------------------------------------------------------------
1 | //go:build windows
2 |
3 | package local
4 |
5 | import (
6 | "fmt"
7 | "path/filepath"
8 | )
9 |
10 | var PluginDir, _ = filepath.Abs("local")
11 |
12 | func cmdPath(name string) string {
13 | return filepath.Join(PluginDir, fmt.Sprintf("%s.exe", name))
14 | }
15 |
--------------------------------------------------------------------------------
/plugin/local/config.go:
--------------------------------------------------------------------------------
1 | package local
2 |
3 | type Config struct {
4 | //Server string `json:"server"`
5 | //Header map[string]string `json:"header"`
6 | //Query map[string]string `json:"query"`
7 | Initialize map[string]string `json:"initialize"`
8 | }
9 |
--------------------------------------------------------------------------------
/plugin/local/driver.go:
--------------------------------------------------------------------------------
1 | package local
2 |
3 | import (
4 | apinto_module "github.com/eolinker/apinto-dashboard/module"
5 | )
6 |
7 | type tDriver struct {
8 | }
9 |
10 | func NewDriver() apinto_module.Driver {
11 | return &tDriver{}
12 | }
13 |
14 | func (d *tDriver) CreatePlugin(define interface{}) (apinto_module.Plugin, error) {
15 | return newTPlugin(define)
16 | }
17 |
--------------------------------------------------------------------------------
/plugin/remote/config.go:
--------------------------------------------------------------------------------
1 | package remote
2 |
3 | type Config struct {
4 | Server string `json:"server"`
5 | Header map[string]string `json:"header"`
6 | Query map[string]string `json:"query"`
7 | Initialize map[string]string `json:"initialize"`
8 | }
9 |
10 | type DtoOpenModeParam struct {
11 | Name string `json:"name"`
12 | Value string `json:"value"`
13 | Type string `json:"type,omitempty"`
14 | }
15 |
--------------------------------------------------------------------------------
/plugin/remote/driver.go:
--------------------------------------------------------------------------------
1 | package remote
2 |
3 | import (
4 | apinto_module "github.com/eolinker/apinto-dashboard/module"
5 | )
6 |
7 | type rDriver struct {
8 | }
9 |
10 | func NewDriver() apinto_module.Driver {
11 | return &rDriver{}
12 | }
13 |
14 | func (d *rDriver) CreatePlugin(define interface{}) (apinto_module.Plugin, error) {
15 | return newRPlugin(define)
16 | }
17 |
--------------------------------------------------------------------------------
/plugin/remote/module.go:
--------------------------------------------------------------------------------
1 | package remote
2 |
3 | import (
4 | apinto_module "github.com/eolinker/apinto-dashboard/module"
5 | )
6 |
7 | type rModule struct {
8 | name string
9 | middlewareHandler []apinto_module.MiddlewareHandler
10 | routersInfo apinto_module.RoutersInfo
11 | }
12 |
13 | func (m *rModule) RoutersInfo() apinto_module.RoutersInfo {
14 | return m.routersInfo
15 | }
16 |
17 | func (m *rModule) Name() string {
18 | return m.name
19 | }
20 |
21 | func (m *rModule) Routers() (apinto_module.Routers, bool) {
22 | if len(m.routersInfo) == 0 {
23 | return nil, false
24 | }
25 | return m, true
26 | }
27 |
28 | func (m *rModule) Middleware() (apinto_module.Middleware, bool) {
29 | return nil, false
30 | }
31 |
32 | func (m *rModule) Support() (apinto_module.ProviderSupport, bool) {
33 | return nil, false
34 | }
35 |
--------------------------------------------------------------------------------
/report/env.go:
--------------------------------------------------------------------------------
1 | package report
2 |
3 | import "time"
4 |
5 | const (
6 | reportAddr = "https://statistics.apinto.com"
7 | periodTime = time.Hour * 24
8 | )
9 |
--------------------------------------------------------------------------------
/scripts/Dockerfile:
--------------------------------------------------------------------------------
1 | # 名称:apinto通用镜像
2 | # 创建时间:2022-10-25
3 | FROM centos:7.9.2009
4 | MAINTAINER liujian
5 |
6 | ENV TZ=Asia/Shanghai
7 | RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
8 |
9 | ARG APP
10 | ARG VERSION
11 | ARG DIR
12 |
13 | RUN mkdir -p /${APP}
14 |
15 | COPY ${DIR}/${APP}_${VERSION}_linux_amd64.tar.gz /${APP}
16 |
17 | RUN cd /${APP} && tar -zxvf ${APP}_${VERSION}_linux_amd64.tar.gz && rm -rf ${APP}_${VERSION}_linux_amd64.tar.gz && ln -snF ${APP}_${VERSION} ${APP}
18 |
19 | WORKDIR /$APP/$APP
20 |
21 | CMD ./docker_run.sh
--------------------------------------------------------------------------------
/scripts/README.md:
--------------------------------------------------------------------------------
1 | ## 编译说明
2 | ### Docker打包指令
3 | ```shell
4 | ./docker_build.sh all {输出目录} {平台}
5 | ```
6 | 示例
7 | ```shell
8 | ./docker_build.sh all apserver mac
9 | ```
--------------------------------------------------------------------------------
/scripts/docker_build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # ===========================================================================
3 | # File: build.sh
4 | # Description: usage: ./build.sh [outdir]
5 | # ===========================================================================
6 |
7 | # exit when any command fails
8 | set -e
9 |
10 | cd "$(dirname "$0")/../"
11 | . ./scripts/init.sh
12 |
13 | #VERSION=`git describe --abbrev=0 --tags`
14 | MODE=$1
15 | OUTPUT_DIR=$(mkdir_output "$2")
16 | PLATFORM=$3
17 | OPTIONS=""
18 | if [[ "${PLATFORM}" == "mac" ]];then
19 | OPTIONS="--platform=linux/amd64"
20 | fi
21 |
22 | # 编译
23 | ./scripts/build.sh ${OUTPUT_DIR} ${MODE} ${VERSION}
24 |
25 | docker build ${OPTIONS} -t docker.eolinker.com/docker/apinto/apserver:${VERSION} --build-arg VERSION=${VERSION} --build-arg APP="apserver" --build-arg DIR=${OUTPUT_DIR} -f scripts/Dockerfile ./
26 |
27 |
--------------------------------------------------------------------------------
/scripts/docker_publish.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # ===========================================================================
3 | # File: build.sh
4 | # Description: usage: ./build.sh [outdir]
5 | # ===========================================================================
6 |
7 | # exit when any command fails
8 | set -e
9 |
10 | cd "$(dirname "$0")/../"
11 | . ./scripts/init.sh
12 |
13 | docker tag docker.eolinker.com/docker/apinto/apserver:${VERSION} docker.eolinker.com/docker/apinto/apserver:latest
14 | docker push docker.eolinker.com/docker/apinto/apserver:${VERSION}
15 | docker push docker.eolinker.com/docker/apinto/apserver:latest
16 |
--------------------------------------------------------------------------------
/scripts/init.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # ===========================================================================
3 | # File: init.sh
4 | # Description: common variables & functions.
5 | # ===========================================================================
6 |
7 | set -e
8 |
9 | # Global variables
10 | RED='\033[0;31m'
11 | GREEN='\033[0;32m'
12 | NC='\033[0m' # No Color
13 |
14 | # Invoke from project root
15 | VERSION=`git describe --abbrev=0 --tags`
16 |
17 | # Version function used for version string comparison
18 | version() { echo "$@" | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }'; }
19 |
20 | # Ensure output directory existed
21 | mkdir_output() {
22 | if [ -z "$1" ]; then
23 | mkdir -p apinto-build
24 | OUTPUT_DIR=$(cd apinto-build > /dev/null && pwd)
25 | else
26 | OUTPUT_DIR="$1"
27 | fi
28 | echo "$OUTPUT_DIR"
29 | }
--------------------------------------------------------------------------------
/scripts/resource/config.yml.tpl:
--------------------------------------------------------------------------------
1 | port: 服务监听的端口号
2 | mysql:
3 | user_name: "数据库用户名"
4 | password: "数据库密码"
5 | ip: "数据库IP地址"
6 | port: 端口号
7 | db: "数据库DB"
8 | error_log:
9 | dir: work/logs # 日志放置目录, 仅支持绝对路径, 不填则默认为执行程序上一层目录的work/logs. 若填写的值不为绝对路径,则以上一层目录为相对路径的根目录,比如填写 work/test/logs, 则目录为可执行程序所在目录的 ../work/test/logs
10 | file_name: error.log # 错误日志文件名
11 | log_level: warning # 错误日志等级,可选:panic,fatal,error,warning,info,debug,trace 不填或者非法则为info
12 | log_expire: 7d # 错误日志过期时间,默认单位为天,d|天,h|小时, 不合法配置默认为7d
13 | log_period: day # 错误日志切割周期,仅支持day、hour
14 | redis:
15 | user_name: "redis集群密码"
16 | password: "redis集群密码"
17 | addr:
18 | - 192.168.128.198:7201
19 | - 192.168.128.198:7202
--------------------------------------------------------------------------------
/store/init.go:
--------------------------------------------------------------------------------
1 | package store
2 |
3 | import (
4 | "github.com/eolinker/eosc/common/bean"
5 | )
6 |
7 | func InitStoreDB(db IDB) {
8 |
9 | bean.Injection(&db)
10 | runHandler(db)
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/store/page.go:
--------------------------------------------------------------------------------
1 | package store
2 |
3 | // PageIndex 用于gorm MYSQL 分页查询
4 | // 示例如下
5 | // db.Limit(pageSize).Offset(entry.PageIndex(pageNum,pageSize))
6 | func PageIndex(pageNum, pageSize int) int {
7 | if pageNum == 0 {
8 | pageNum = 1
9 | }
10 | return (pageNum - 1) * pageSize
11 | }
12 |
--------------------------------------------------------------------------------
/store/register.go:
--------------------------------------------------------------------------------
1 | package store
2 |
3 | type Handler func(db IDB)
4 |
5 | var (
6 | handlers []Handler
7 | )
8 |
9 | func RegisterStore(h Handler) {
10 | handlers = append(handlers, h)
11 | }
12 | func runHandler(db IDB) {
13 | for _, h := range handlers {
14 | h(db)
15 | }
16 | }
17 |
--------------------------------------------------------------------------------