Pull request: home: show version in install api

Closes #4026.

Squashed commit of the following:

commit bcd1315a10e819daee3aee323427d90a27860b4a
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jan 18 14:57:49 2022 +0300

    openapi: fix example

commit b56e27c5ac1fc7c3f595057d77607479d72ec50a
Author: Ildar Kamalov <ik@adguard.com>
Date:   Tue Jan 18 14:55:51 2022 +0300

    client: show version on install page

commit 95dfbfaa1235deef7b55e51457d11c677f6ef6b5
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jan 18 14:29:08 2022 +0300

    home: show version in install api
This commit is contained in:
Ainar Garipov 2022-01-18 15:05:34 +03:00
parent 061136508e
commit 813a06d09a
6 changed files with 64 additions and 33 deletions

View File

@ -13,6 +13,12 @@ const Version = () => {
checkUpdateFlag, checkUpdateFlag,
} = useSelector((state) => state?.dashboard ?? {}, shallowEqual); } = useSelector((state) => state?.dashboard ?? {}, shallowEqual);
const {
dnsVersion: installDnsVersion,
} = useSelector((state) => state?.install ?? {}, shallowEqual);
const version = dnsVersion || installDnsVersion;
const onClick = () => { const onClick = () => {
dispatch(getVersion(true)); dispatch(getVersion(true));
}; };
@ -20,11 +26,12 @@ const Version = () => {
return ( return (
<div className="version"> <div className="version">
<div className="version__text"> <div className="version__text">
{dnsVersion {version && (
&& <> <>
<Trans>version</Trans>:&nbsp; <Trans>version</Trans>:&nbsp;
<span className="version__value" title={dnsVersion}>{dnsVersion}</span> <span className="version__value" title={version}>{version}</span>
</>} </>
)}
{checkUpdateFlag && <button {checkUpdateFlag && <button
type="button" type="button"
className="btn btn-icon btn-icon-sm btn-outline-primary btn-sm ml-2" className="btn btn-icon btn-icon-sm btn-outline-primary btn-sm ml-2"

View File

@ -12,13 +12,19 @@ const install = handleActions({
[actions.getDefaultAddressesRequest]: (state) => ({ ...state, processingDefault: true }), [actions.getDefaultAddressesRequest]: (state) => ({ ...state, processingDefault: true }),
[actions.getDefaultAddressesFailure]: (state) => ({ ...state, processingDefault: false }), [actions.getDefaultAddressesFailure]: (state) => ({ ...state, processingDefault: false }),
[actions.getDefaultAddressesSuccess]: (state, { payload }) => { [actions.getDefaultAddressesSuccess]: (state, { payload }) => {
const { interfaces } = payload; const { interfaces, version } = payload;
const web = { ...state.web, port: payload.web_port }; const web = { ...state.web, port: payload.web_port };
const dns = { ...state.dns, port: payload.dns_port }; const dns = { ...state.dns, port: payload.dns_port };
const newState = { const newState = {
...state, web, dns, interfaces, processingDefault: false, ...state,
web,
dns,
interfaces,
processingDefault: false,
dnsVersion: version,
}; };
return newState; return newState;
}, },
@ -64,6 +70,7 @@ const install = handleActions({
error: '', error: '',
}, },
interfaces: {}, interfaces: {},
dnsVersion: '',
}); });
export default combineReducers({ export default combineReducers({

View File

@ -17,6 +17,7 @@ import (
"github.com/AdguardTeam/AdGuardHome/internal/aghalgo" "github.com/AdguardTeam/AdGuardHome/internal/aghalgo"
"github.com/AdguardTeam/AdGuardHome/internal/aghhttp" "github.com/AdguardTeam/AdGuardHome/internal/aghhttp"
"github.com/AdguardTeam/AdGuardHome/internal/aghnet" "github.com/AdguardTeam/AdGuardHome/internal/aghnet"
"github.com/AdguardTeam/AdGuardHome/internal/version"
"github.com/AdguardTeam/golibs/errors" "github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/log" "github.com/AdguardTeam/golibs/log"
) )
@ -24,13 +25,23 @@ import (
// getAddrsResponse is the response for /install/get_addresses endpoint. // getAddrsResponse is the response for /install/get_addresses endpoint.
type getAddrsResponse struct { type getAddrsResponse struct {
Interfaces map[string]*aghnet.NetInterface `json:"interfaces"` Interfaces map[string]*aghnet.NetInterface `json:"interfaces"`
WebPort int `json:"web_port"`
DNSPort int `json:"dns_port"` // Version is the version of AdGuard Home.
//
// TODO(a.garipov): In the new API, rename this endpoint to something more
// general, since there will be more information here than just network
// interfaces.
Version string `json:"version"`
WebPort int `json:"web_port"`
DNSPort int `json:"dns_port"`
} }
// handleInstallGetAddresses is the handler for /install/get_addresses endpoint. // handleInstallGetAddresses is the handler for /install/get_addresses endpoint.
func (web *Web) handleInstallGetAddresses(w http.ResponseWriter, r *http.Request) { func (web *Web) handleInstallGetAddresses(w http.ResponseWriter, r *http.Request) {
data := getAddrsResponse{ data := getAddrsResponse{
Version: version.Version(),
WebPort: defaultPortHTTP, WebPort: defaultPortHTTP,
DNSPort: defaultPortDNS, DNSPort: defaultPortDNS,
} }
@ -279,10 +290,11 @@ type applyConfigReqEnt struct {
} }
type applyConfigReq struct { type applyConfigReq struct {
Web applyConfigReqEnt `json:"web"` Username string `json:"username"`
DNS applyConfigReqEnt `json:"dns"` Password string `json:"password"`
Username string `json:"username"`
Password string `json:"password"` Web applyConfigReqEnt `json:"web"`
DNS applyConfigReqEnt `json:"dns"`
} }
// copyInstallSettings copies the installation parameters between two // copyInstallSettings copies the installation parameters between two
@ -533,10 +545,11 @@ type applyConfigReqEntBeta struct {
// TODO(e.burkov): This should removed with the API v1 when the appropriate // TODO(e.burkov): This should removed with the API v1 when the appropriate
// functionality will appear in default applyConfigReq. // functionality will appear in default applyConfigReq.
type applyConfigReqBeta struct { type applyConfigReqBeta struct {
Web applyConfigReqEntBeta `json:"web"` Username string `json:"username"`
DNS applyConfigReqEntBeta `json:"dns"` Password string `json:"password"`
Username string `json:"username"`
Password string `json:"password"` Web applyConfigReqEntBeta `json:"web"`
DNS applyConfigReqEntBeta `json:"dns"`
} }
// handleInstallConfigureBeta is a substitution of /install/configure handler // handleInstallConfigureBeta is a substitution of /install/configure handler

View File

@ -62,18 +62,10 @@ func Version() (v string) {
return version return version
} }
// Common formatting constants.
const (
sp = " "
nl = "\n"
tb = "\t"
nltb = nl + tb
)
// Constants defining the format of module information string. // Constants defining the format of module information string.
const ( const (
modInfoAtSep = "@" modInfoAtSep = "@"
modInfoDevSep = sp modInfoDevSep = " "
modInfoSumLeft = " (sum: " modInfoSumLeft = " (sum: "
modInfoSumRight = ")" modInfoSumRight = ")"
) )
@ -142,6 +134,7 @@ const (
func Verbose() (v string) { func Verbose() (v string) {
b := &strings.Builder{} b := &strings.Builder{}
const nl = "\n"
stringutil.WriteToBuilder( stringutil.WriteToBuilder(
b, b,
vFmtAGHHdr, vFmtAGHHdr,
@ -178,7 +171,7 @@ func Verbose() (v string) {
stringutil.WriteToBuilder(b, nl, vFmtDepsHdr) stringutil.WriteToBuilder(b, nl, vFmtDepsHdr)
for _, dep := range info.Deps { for _, dep := range info.Deps {
if depStr := fmtModule(dep); depStr != "" { if depStr := fmtModule(dep); depStr != "" {
stringutil.WriteToBuilder(b, nltb, depStr) stringutil.WriteToBuilder(b, "\n\t", depStr)
} }
} }

View File

@ -2,9 +2,16 @@
<!-- TODO(a.garipov): Reformat in accordance with the KeepAChangelog spec. --> <!-- TODO(a.garipov): Reformat in accordance with the KeepAChangelog spec. -->
## v0.107: API changes ## v0.107.3: API changes
## The new field `"cached"` in `QueryLogItem` ### The new field `"version"` in `AddressesInfo`
* The new field `"version"` in `GET /install/get_addresses` is the version of
the AdGuard Home instance.
## v0.107.0: API changes
### The new field `"cached"` in `QueryLogItem`
* The new field `"cached"` in `GET /control/querylog` is true if the response is * The new field `"cached"` in `GET /control/querylog` is true if the response is
served from cache instead of being resolved by an upstream server. served from cache instead of being resolved by an upstream server.

View File

@ -1264,7 +1264,7 @@
'type': 'boolean' 'type': 'boolean'
'version': 'version':
'type': 'string' 'type': 'string'
'example': '0.1' 'example': 'v0.123.4'
'language': 'language':
'type': 'string' 'type': 'string'
'example': 'en' 'example': 'en'
@ -2221,19 +2221,23 @@
'description': 'AdGuard Home addresses configuration' 'description': 'AdGuard Home addresses configuration'
'required': 'required':
- 'dns_port' - 'dns_port'
- 'web_port'
- 'interfaces' - 'interfaces'
- 'version'
- 'web_port'
'properties': 'properties':
'dns_port': 'dns_port':
'type': 'integer' 'type': 'integer'
'format': 'uint16' 'format': 'uint16'
'example': 53 'example': 53
'interfaces':
'$ref': '#/components/schemas/NetInterfaces'
'version':
'type': 'string'
'example': 'v0.123.4'
'web_port': 'web_port':
'type': 'integer' 'type': 'integer'
'format': 'uint16' 'format': 'uint16'
'example': 80 'example': 80
'interfaces':
'$ref': '#/components/schemas/NetInterfaces'
'AddressesInfoBeta': 'AddressesInfoBeta':
'type': 'object' 'type': 'object'
'description': 'AdGuard Home addresses configuration' 'description': 'AdGuard Home addresses configuration'