Merge pull request #899 from gravitl/develop

Upgrade to v0.12.0
This commit is contained in:
dcarns 2022-03-15 09:26:16 -04:00 committed by GitHub
commit aa821e0304
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
43 changed files with 992 additions and 158 deletions

8
.fpm Normal file
View file

@ -0,0 +1,8 @@
--name netclient
--license sspl
--depends wireguard-tools
--description "Netmaker's netclient agent and CLI"
--url "https//:github.com/gravitl/netmaker"
--maintainer "info@gravitl.com"
--vendor Gravitl

72
.github/ISSUE_TEMPLATE/bug-report.yml vendored Normal file
View file

@ -0,0 +1,72 @@
name: Bug Report
description: File a bug report
title: "[Bug]: "
labels: ["bug", "triage"]
assignees: ["ok-john", "0xdcarns", "afeiszli", "mattkasun"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!
- type: input
id: contact
attributes:
label: Contact Details
description: How can we get in touch with you if we need more info?
placeholder: ex. email@example.com
validations:
required: false
- type: textarea
id: what-happened
attributes:
label: What happened?
description: Also tell us, what did you expect to happen?
placeholder: Tell us what you see!
value: "A bug happened!"
validations:
required: true
- type: dropdown
id: version
attributes:
label: Version
description: What version are you running?
options:
- v0.12.0
- v0.11.1
- v0.11.0
- v0.10.0
- v0.9.4
- v0.9.3
- v0.9.2
- v0.9.1
- v0.9.0
- v0.8.5
- Not sure
- Not listed
validations:
required: true
- type: dropdown
id: os
attributes:
label: What OS are you using?
multiple: true
options:
- Linux
- FreeBSD
- Windows
- Mac
- Unlisted
- type: textarea
id: logs
attributes:
label: Relevant log output
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
render: shell
- type: checkboxes
id: terms
attributes:
label: Contributing guidelines
description: Have you read [CONTRIBUTING.md](https://github.com/gravitl/netmaker/blob/master/CONTRIBUTING.md)
options:
- label: Yes, I did.
required: true

View file

@ -5,16 +5,17 @@ on:
inputs:
version:
description: 'Netmaker version'
required: false
required: true
release:
types: [published]
jobs:
build:
version:
runs-on: ubuntu-latest
outputs:
tag: ${{ steps.echo.outputs.tag }}
version: ${{ steps.echo.outputs.version }}
steps:
- name: Get Version Number
run: |
if [[ -n "${{ github.event.inputs.version }}" ]]; then
@ -23,32 +24,43 @@ jobs:
NETMAKER_VERSION=$(curl -fsSL https://api.github.com/repos/gravitl/netmaker/tags | grep 'name' | head -1 | cut -d'"' -f4)
fi
echo "NETMAKER_VERSION=${NETMAKER_VERSION}" >> $GITHUB_ENV
# remove everything but digits and . for package (deb, rpm, etc) versions
PACKAGE_VERSION=$(echo ${NETMAKER_VERSION} | tr -cd '[:digit:].')
echo "PACKAGE_VERSION=${PACKAGE_VERSION}" >> $GITHUB_ENV
- name: Echo
id: echo
run: |
echo ${{ env.NETMAKER_VERSION }}
echo ${{ env.PACKAGE_VERSION }}
if [[ -z ${{ env.NETMAKER_VERSION }} || -z ${{ env.PACKAGE_VERSION }} ]]
then
exit 1
fi
echo "::set-output name=tag::${{ env.NETMAKER_VERSION }}"
echo "::set-output name=version::${{ env.PACKAGE_VERSION }}"
netmaker:
runs-on: ubuntu-latest
needs: version
steps:
- name: set variables
run: |
echo ${{ needs.version.outputs.tag }} ${{ needs.version.outputs.version }}
TAG=${{needs.version.outputs.tag}}
VERSION=${{needs.version.outputs.version}}
if [[ -z ${VERSION} || -z ${TAG} ]]; then
exit 1
fi
echo "NETMAKER_VERSION=${TAG}" >> $GITHUB_ENV
echo "PACKAGE_VERSION=${VERSION}" >> $GITHUB_ENV
- name: Checkout
uses: actions/checkout@v2
- name: Setup go
uses: actions/setup-go@v2
with:
go-version: 1.17
- name: Build
run: |
env CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -ldflags="-X 'main.version=${NETMAKER_VERSION}'" -o build/netmaker main.go
cd netclient
env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-X 'main.version=${NETMAKER_VERSION}'" -o build/netclient main.go
env CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=5 go build -ldflags="-X 'main.version=${NETMAKER_VERSION}'" -o build/netclient-arm5/netclient main.go
env CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=6 go build -ldflags="-X 'main.version=${NETMAKER_VERSION}'" -o build/netclient-arm6/netclient main.go
env CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=7 go build -ldflags="-X 'main.version=${NETMAKER_VERSION}'" -o build/netclient-arm7/netclient main.go
env CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags="-X 'main.version=${NETMAKER_VERSION}'" -o build/netclient-arm64/netclient main.go
env CGO_ENABLED=0 GOOS=linux GOARCH=mipsle go build -ldflags "-s -w -X 'main.version=$NETMAKER_VERSION'" -o build/netclient-mipsle/netclient main.go && upx build/netclient-mipsle/netclient
env CGO_ENABLED=0 GOOS=freebsd GOARCH=amd64 go build -ldflags="-X 'main.Version=${NETMAKER_VERSION}'" -o build/netclient-freebsd/netclient main.go
env CGO_ENABLED=0 GOOS=freebsd GOARCH=arm GOARM=5 go build -ldflags="-X 'main.version=${NETMAKER_VERSION}'" -o build/netclient-freebsd-arm5/netclient main.go
env CGO_ENABLED=0 GOOS=freebsd GOARCH=arm GOARM=6 go build -ldflags="-X 'main.version=${NETMAKER_VERSION}'" -o build/netclient-freebsd-arm6/netclient main.go
env CGO_ENABLED=0 GOOS=freebsd GOARCH=arm GOARM=7 go build -ldflags="-X 'main.version=${NETMAKER_VERSION}'" -o build/netclient-freebsd-arm7/netclient main.go
env CGO_ENABLED=0 GOOS=freebsd GOARCH=arm64 go build -ldflags="-X 'main.version=${NETMAKER_VERSION}'" -o build/netclient-freebsd-arm64/netclient main.go
env CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -ldflags="-X 'main.version=${NETMAKER_VERSION}'" -o build/netclient-darwin/netclient main.go
env CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -ldflags="-X 'main.version=${NETMAKER_VERSION}'" -o build/netclient-darwin-arm64/netclient main.go
- name: Upload netmaker x86 to Release
uses: svenstaro/upload-release-action@v2
with:
@ -59,7 +71,28 @@ jobs:
prerelease: true
asset_name: netmaker
- name: Upload x86 to Release
netclient-x86:
runs-on: ubuntu-latest
needs: version
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set Variables
run: |
TAG=${{needs.version.outputs.tag}}
VERSION=${{needs.version.outputs.version}}
echo "NETMAKER_VERSION=${TAG}" >> $GITHUB_ENV
echo "PACKAGE_VERSION=${VERSION}" >> $GITHUB_ENV
- name: Setup go
uses: actions/setup-go@v2
with:
go-version: 1.17
- name: Build
run: |
cd netclient
env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-X 'main.version=${NETMAKER_VERSION}'" -o build/netclient main.go
- name: Upload netclient x86 to Release
continue-on-error: true
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
@ -69,26 +102,100 @@ jobs:
prerelease: true
asset_name: netclient
- name: Upload arm5 to Release
- name: Package x86 deb
continue-on-error: true
uses: gravitl/github-action-fpm@master
with:
fpm_args: './netclient/build/netclient=/sbin/netclient ./netclient/build/netclient.service=/lib/systemd/system/netclient.service'
fpm_opts: '-s dir -t deb --architecture amd64 --version ${{ env.PACKAGE_VERSION }}'
- name: Upload x86 deb to Release
continue-on-error: true
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: netclient/build/netclient-arm5/netclient
file: netclient_${{ env.PACKAGE_VERSION }}_amd64.deb
tag: ${{ env.NETMAKER_VERSION }}
overwrite: true
prerelease: true
asset_name: netclient_${{ env.PACKAGE_VERSION }}_amd64.deb
- name: Package x86 rpm
continue-on-error: true
uses: gravitl/github-action-fpm@master
with:
fpm_args: './netclient/build/netclient=/sbin/netclient ./netclient/build/netclient.service=/lib/systemd/system/netclient.service'
fpm_opts: '-s dir -t rpm --architecture amd64 --version ${{ env.PACKAGE_VERSION }}'
- name: Upload x86 rpm to Release
continue-on-error: true
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: netclient-${{ env.PACKAGE_VERSION }}-1.x86_64.rpm
tag: ${{ env.NETMAKER_VERSION }}
overwrite: true
prerelease: true
asset_name: netclient-${{ env.PACKAGE_VERSION }}-1.x86_64.rpm
- name: Package x86 pacman
continue-on-error: true
uses: gravitl/github-action-fpm@master
with:
# arch has particular path requirements --- cannot write to a symbolic link e.g. /sbin and /lib
fpm_args: './netclient/build/netclient=/usr/bin/netclient ./netclient/build/netclient.service=/usr/lib/systemd/system/netclient.service'
fpm_opts: '-s dir -t pacman --architecture amd64 --version ${{ env.PACKAGE_VERSION }}'
- name: Upload x86 pacman to Release
continue-on-error: true
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: netclient-${{ env.PACKAGE_VERSION }}-1-x86_64.pkg.tar.zst
tag: ${{ env.NETMAKER_VERSION }}
overwrite: true
prerelease: true
asset_name: netclient-${{ env.PACKAGE_VERSION }}-1-x86_64.pkg.tar.zst
netclient-arm:
runs-on: ubuntu-latest
needs: version
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set Variables
run: |
TAG=${{needs.version.outputs.tag}}
VERSION=${{needs.version.outputs.version}}
echo "NETMAKER_VERSION=${TAG}" >> $GITHUB_ENV
echo "PACKAGE_VERSION=${VERSION}" >> $GITHUB_ENV
- name: Setup go
uses: actions/setup-go@v2
with:
go-version: 1.17
- name: Build
run: |
cd netclient
env CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=5 go build -ldflags="-X 'main.version=${NETMAKER_VERSION}'" -o build/netclient-arm5/netclient main.go
env CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=6 go build -ldflags="-X 'main.version=${NETMAKER_VERSION}'" -o build/netclient-arm6/netclient main.go
env CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=7 go build -ldflags="-X 'main.version=${NETMAKER_VERSION}'" -o build/netclient-arm7/netclient main.go
env CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags="-X 'main.version=${NETMAKER_VERSION}'" -o build/netclient-arm64/netclient main.go
- name: Upload arm5 to Release
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: netclient/build/netclient-arm5/netclient
tag: ${{ env.NETMAKER_VERSION }}
overwrite: true
prerelease: true
asset_name: netclient-arm5
- name: Upload arm6 to Release
uses: svenstaro/upload-release-action@v2
with:
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: netclient/build/netclient-arm6/netclient
tag: ${{ env.NETMAKER_VERSION }}
overwrite: true
prerelease: true
asset_name: netclient-arm6
- name: Upload arm7 to Release
uses: svenstaro/upload-release-action@v2
with:
@ -98,8 +205,9 @@ jobs:
overwrite: true
prerelease: true
asset_name: netclient-arm7
- name: Upload arm64 to Release
continue-on-error: true
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
@ -108,7 +216,59 @@ jobs:
overwrite: true
prerelease: true
asset_name: netclient-arm64
- name: Package arm64 deb
continue-on-error: true
uses: gravitl/github-action-fpm@master
with:
fpm_args: './netclient/build/netclient-arm64/netclient=/sbin/netclient ./netclient/build/netclient.service=/lib/systemd/netclient.service'
fpm_opts: '-s dir -t deb --architecture arm64 --version ${{ env.PACKAGE_VERSION }}'
- name: Upload arm deb to Release
continue-on-error: true
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: netclient_${{ env.PACKAGE_VERSION }}_arm64.deb
tag: ${{ env.NETMAKER_VERSION }}
overwrite: true
prerelease: true
asset_name: netclient_${{ env.PACKAGE_VERSION }}_arm64.deb
- name: Package arm64 rpm
continue-on-error: true
uses: gravitl/github-action-fpm@master
with:
fpm_args: './netclient/build/netclient-arm64/netclient=/sbin/netclient ./netclient/build/netclient.service=/lib/systemd/netclient.service'
fpm_opts: '-s dir -t rpm --architecture arm64 --version ${{ env.PACKAGE_VERSION }}'
- name: Upload arm64 rpm to Release
continue-on-error: true
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: netclient-${{ env.PACKAGE_VERSION }}-1.aarch64.rpm
tag: ${{ env.NETMAKER_VERSION }}
overwrite: true
prerelease: true
asset_name: netclient-${{ env.PACKAGE_VERSION }}-1.aarch4.rpm
netclient-mipsle:
runs-on: ubuntu-latest
needs: version
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set Variables
run: |
TAG=${{needs.version.outputs.tag}}
VERSION=${{needs.version.outputs.version}}
echo "NETMAKER_VERSION=${TAG}" >> $GITHUB_ENV
echo "PACKAGE_VERSION=${VERSION}" >> $GITHUB_ENV
- name: Setup go
uses: actions/setup-go@v2
with:
go-version: 1.17
- name: Build
run: |
cd netclient
env CGO_ENABLED=0 GOOS=linux GOARCH=mipsle go build -ldflags "-s -w -X 'main.version=$NETMAKER_VERSION'" -o build/netclient-mipsle/netclient main.go && upx build/netclient-mipsle/netclient
- name: Upload mipsle to Release
uses: svenstaro/upload-release-action@v2
with:
@ -118,6 +278,31 @@ jobs:
overwrite: true
prerelease: true
asset_name: netclient-mipsle
netclient-freebsd:
runs-on: ubuntu-latest
needs: version
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set Variables
run: |
TAG=${{needs.version.outputs.tag}}
VERSION=${{needs.version.outputs.version}}
echo "NETMAKER_VERSION=${TAG}" >> $GITHUB_ENV
echo "PACKAGE_VERSION=${VERSION}" >> $GITHUB_ENV
- name: Setup go
uses: actions/setup-go@v2
with:
go-version: 1.17
- name: Build
run: |
cd netclient
env CGO_ENABLED=0 GOOS=freebsd GOARCH=amd64 go build -ldflags="-X 'main.Version=${NETMAKER_VERSION}'" -o build/netclient-freebsd/netclient main.go
env CGO_ENABLED=0 GOOS=freebsd GOARCH=arm GOARM=5 go build -ldflags="-X 'main.version=${NETMAKER_VERSION}'" -o build/netclient-freebsd-arm5/netclient main.go
env CGO_ENABLED=0 GOOS=freebsd GOARCH=arm GOARM=6 go build -ldflags="-X 'main.version=${NETMAKER_VERSION}'" -o build/netclient-freebsd-arm6/netclient main.go
env CGO_ENABLED=0 GOOS=freebsd GOARCH=arm GOARM=7 go build -ldflags="-X 'main.version=${NETMAKER_VERSION}'" -o build/netclient-freebsd-arm7/netclient main.go
env CGO_ENABLED=0 GOOS=freebsd GOARCH=arm64 go build -ldflags="-X 'main.version=${NETMAKER_VERSION}'" -o build/netclient-freebsd-arm64/netclient main.go
- name: Upload freebsd to Release
uses: svenstaro/upload-release-action@v2
@ -168,8 +353,29 @@ jobs:
overwrite: true
prerelease: true
asset_name: netclient-freebsd-arm64
- name: Upload darwin to Release
netclient-darwin:
runs-on: ubuntu-latest
needs: version
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set Variables
run: |
TAG=${{needs.version.outputs.tag}}
VERSION=${{needs.version.outputs.version}}
echo "NETMAKER_VERSION=${TAG}" >> $GITHUB_ENV
echo "PACKAGE_VERSION=${VERSION}" >> $GITHUB_ENV
- name: Setup go
uses: actions/setup-go@v2
with:
go-version: 1.17
- name: Build
run: |
cd netclient
env CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -ldflags="-X 'main.version=${NETMAKER_VERSION}'" -o build/netclient-darwin/netclient main.go
env CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -ldflags="-X 'main.version=${NETMAKER_VERSION}'" -o build/netclient-darwin-arm64/netclient main.go
- name: Upload darwin-arm64 to Release
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}

View file

@ -1,8 +1,9 @@
name: Purge untagged images from GHCR
on:
workflow_dispatch
workflow_dispatch:
schedule:
- cron: '1 1 1 * *'
jobs:
purge:
runs-on: ubuntu-latest
@ -15,7 +16,7 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }}
organization: gravitl
container: netmaker
dry-run: true # Dry-run first, then change to `false`
dry-run: false # Dry-run first, then change to `false`
untagged: true
- name: Prune Netclient
uses: vlaurin/action-ghcr-prune@main
@ -23,6 +24,6 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }}
organization: gravitl
container: netclient
dry-run: true # Dry-run first, then change to `false`
dry-run: false # Dry-run first, then change to `false`
untagged: true

3
.gitignore vendored
View file

@ -6,6 +6,7 @@ netmaker-amd64
netclient/netclient
netclient/build
netclient/build/
!netclient/build/netclient.service
netclient/files/netclient
netclient/netclient-amd64
netclient/netclient-arm
@ -14,6 +15,8 @@ netclient/netclient-32
netclient/netclient32
netclient/netclient.exe
config/dnsconfig/
controllers/config/dnsconfig/
controllers/data/
data/
.vscode/
.idea/

View file

@ -3,12 +3,12 @@
<img src="netmaker.png" width="75%"><break/>
</p>
<p align="center">
<i>Create and control automated virtual networks.</i>
a platform for blazing fast and dynamic virtual networks
</p>
<p align="center">
<a href="https://github.com/gravitl/netmaker/releases">
<img src="https://img.shields.io/badge/Version-0.11.1-informational?style=flat-square" />
<img src="https://img.shields.io/badge/Version-0.12.0-informational?style=flat-square" />
</a>
<a href="https://hub.docker.com/r/gravitl/netmaker/tags">
<img src="https://img.shields.io/docker/pulls/gravitl/netmaker" />

View file

@ -3,7 +3,7 @@ version: "3.4"
services:
netmaker:
container_name: netmaker
image: gravitl/netmaker:v0.11.1
image: gravitl/netmaker:v0.12.0
volumes:
- dnsconfig:/root/config/dnsconfig
- sqldata:/root/data
@ -45,7 +45,7 @@ services:
container_name: netmaker-ui
depends_on:
- netmaker
image: gravitl/netmaker-ui:v0.11.1
image: gravitl/netmaker-ui:v0.12.0
links:
- "netmaker:api"
ports:

View file

@ -3,7 +3,7 @@ version: "3.4"
services:
netmaker:
container_name: netmaker
image: gravitl/netmaker:v0.11.1
image: gravitl/netmaker:v0.12.0
volumes:
- dnsconfig:/root/config/dnsconfig
- /usr/bin/wg:/usr/bin/wg
@ -41,7 +41,7 @@ services:
container_name: netmaker-ui
depends_on:
- netmaker
image: gravitl/netmaker-ui:0.11.1
image: gravitl/netmaker-ui:0.12.0
links:
- "netmaker:api"
ports:

View file

@ -3,7 +3,7 @@ version: "3.4"
services:
netmaker:
container_name: netmaker
image: gravitl/netmaker:v0.11.1
image: gravitl/netmaker:v0.12.0
volumes:
- dnsconfig:/root/config/dnsconfig
- sqldata:/root/data
@ -45,7 +45,7 @@ services:
container_name: netmaker-ui
depends_on:
- netmaker
image: gravitl/netmaker-ui:v0.11.1
image: gravitl/netmaker-ui:v0.12.0
links:
- "netmaker:api"
ports:

View file

@ -3,7 +3,7 @@ version: "3.4"
services:
netmaker:
container_name: netmaker
image: gravitl/netmaker:v0.11.1
image: gravitl/netmaker:v0.12.0
volumes:
- dnsconfig:/root/config/dnsconfig
- sqldata:/root/data
@ -45,7 +45,7 @@ services:
container_name: netmaker-ui
depends_on:
- netmaker
image: gravitl/netmaker-ui:v0.11.1
image: gravitl/netmaker-ui:v0.12.0
links:
- "netmaker:api"
ports:

View file

@ -2,7 +2,7 @@ services:
netmaker: # The Primary Server for running Netmaker
privileged: true # Necessary to run sudo/root level commands on host system. Likely using this if running with host networking on.
container_name: netmaker
image: gravitl/netmaker:v0.11.1
image: gravitl/netmaker:v0.12.0
volumes: # Volume mounts necessary for CLIENT_MODE to control wireguard networking on host (except dnsconfig, which is where dns config files are stored for use by CoreDNS)
- dnsconfig:/root/config/dnsconfig # Netmaker writes Corefile to this location, which gets mounted by CoreDNS for DNS configuration.
- sqldata:/root/data
@ -44,7 +44,7 @@ services:
container_name: netmaker-ui
depends_on:
- netmaker
image: gravitl/netmaker-ui:v0.11.1
image: gravitl/netmaker-ui:v0.12.0
links:
- "netmaker:api"
ports:

View file

@ -3,7 +3,7 @@ version: "3.4"
services:
netmaker:
container_name: netmaker
image: gravitl/netmaker:v0.11.1
image: gravitl/netmaker:v0.12.0
volumes:
- dnsconfig:/root/config/dnsconfig
- sqldata:/root/data
@ -45,7 +45,7 @@ services:
container_name: netmaker-ui
depends_on:
- netmaker
image: gravitl/netmaker-ui:v0.11.1
image: gravitl/netmaker-ui:v0.12.0
links:
- "netmaker:api"
ports:

View file

@ -1,2 +1 @@
10.0.0.1 testnode.skynet
10.0.0.2 myhost.skynet
10.0.0.2 testnode.skynet myhost.skynet

View file

@ -151,9 +151,15 @@ func getExtClientConf(w http.ResponseWriter, r *http.Request) {
if network.DefaultExtClientDNS != "" {
defaultDNS = "DNS = " + network.DefaultExtClientDNS
}
defaultMTU := 1420
if gwnode.MTU != 0 {
defaultMTU = int(gwnode.MTU)
}
config := fmt.Sprintf(`[Interface]
Address = %s
PrivateKey = %s
MTU = %d
%s
[Peer]
@ -164,6 +170,7 @@ Endpoint = %s
`, client.Address+"/32",
client.PrivateKey,
defaultMTU,
defaultDNS,
gwnode.PublicKey,
newAllowedIPs,
@ -228,6 +235,8 @@ func createExtClient(w http.ResponseWriter, r *http.Request) {
return
}
extclient.IngressGatewayEndpoint = node.Endpoint + ":" + strconv.FormatInt(int64(node.ListenPort), 10)
// TODO, could rely on network template as well in future
extclient.Enabled = true
err = json.NewDecoder(r.Body).Decode(&extclient)
if err != nil && !errors.Is(err, io.EOF) {
returnErrorResponse(w, r, formatError(err, "internal"))
@ -238,6 +247,7 @@ func createExtClient(w http.ResponseWriter, r *http.Request) {
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
logger.Log(0, r.Header.Get("user"), "created new ext client on network", networkName)
w.WriteHeader(http.StatusOK)
err = mq.PublishExtPeerUpdate(&node)
if err != nil {
@ -268,12 +278,20 @@ func updateExtClient(w http.ResponseWriter, r *http.Request) {
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
newclient, err := logic.UpdateExtClient(newExtClient.ClientID, params["network"], &oldExtClient)
var changedEnabled = newExtClient.Enabled != oldExtClient.Enabled // indicates there was a change in enablement
newclient, err := logic.UpdateExtClient(newExtClient.ClientID, params["network"], newExtClient.Enabled, &oldExtClient)
if err != nil {
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
logger.Log(1, r.Header.Get("user"), "updated client", newExtClient.ClientID)
logger.Log(0, r.Header.Get("user"), "updated ext client", newExtClient.ClientID)
if changedEnabled { // need to send a peer update to the ingress node as enablement of one of it's clients has changed
if ingressNode, err := logic.GetNodeByID(newclient.IngressGatewayID); err == nil {
if err = mq.PublishExtPeerUpdate(&ingressNode); err != nil {
logger.Log(1, "error setting ext peers on", ingressNode.ID, ":", err.Error())
}
}
}
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(newclient)
}
@ -311,7 +329,7 @@ func deleteExtClient(w http.ResponseWriter, r *http.Request) {
if err != nil {
logger.Log(1, "error setting ext peers on "+ingressnode.ID+": "+err.Error())
}
logger.Log(1, r.Header.Get("user"),
logger.Log(0, r.Header.Get("user"),
"Deleted extclient client", params["clientid"], "from network", params["network"])
returnSuccessResponse(w, r, params["clientid"]+" deleted.")
}

View file

@ -11,6 +11,7 @@ import (
"github.com/gravitl/netmaker/database"
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/logic"
"github.com/gravitl/netmaker/logic/acls"
"github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/mq"
"github.com/gravitl/netmaker/servercfg"
@ -34,6 +35,9 @@ func networkHandlers(r *mux.Router) {
r.HandleFunc("/api/networks/{networkname}/keys", securityCheck(false, http.HandlerFunc(createAccessKey))).Methods("POST")
r.HandleFunc("/api/networks/{networkname}/keys", securityCheck(false, http.HandlerFunc(getAccessKeys))).Methods("GET")
r.HandleFunc("/api/networks/{networkname}/keys/{name}", securityCheck(false, http.HandlerFunc(deleteAccessKey))).Methods("DELETE")
// ACLs
r.HandleFunc("/api/networks/{networkname}/acls", securityCheck(true, http.HandlerFunc(updateNetworkACL))).Methods("PUT")
r.HandleFunc("/api/networks/{networkname}/acls", securityCheck(true, http.HandlerFunc(getNetworkACL))).Methods("GET")
}
//simple get all networks function
@ -231,6 +235,58 @@ func updateNetworkNodeLimit(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(network)
}
func updateNetworkACL(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
var params = mux.Vars(r)
netname := params["networkname"]
var networkACLChange acls.ACLContainer
networkACLChange, err := networkACLChange.Get(acls.ContainerID(netname))
if err != nil {
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
_ = json.NewDecoder(r.Body).Decode(&networkACLChange)
newNetACL, err := networkACLChange.Save(acls.ContainerID(netname))
if err != nil {
returnErrorResponse(w, r, formatError(err, "badrequest"))
return
}
logger.Log(1, r.Header.Get("user"), "updated ACLs for network", netname)
// send peer updates
if servercfg.IsMessageQueueBackend() {
serverNode, err := logic.GetNetworkServerLocal(netname)
if err != nil {
logger.Log(1, "failed to find server node after ACL update on", netname)
} else {
if err = logic.ServerUpdate(&serverNode, false); err != nil {
logger.Log(1, "failed to update server node after ACL update on", netname)
}
if err = mq.PublishPeerUpdate(&serverNode); err != nil {
logger.Log(0, "failed to publish peer update after ACL update on", netname)
}
}
}
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(newNetACL)
}
func getNetworkACL(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
var params = mux.Vars(r)
netname := params["networkname"]
var networkACL acls.ACLContainer
networkACL, err := networkACL.Get(acls.ContainerID(netname))
if err != nil {
returnErrorResponse(w, r, formatError(err, "internal"))
return
}
logger.Log(2, r.Header.Get("user"), "fetched acl for network", netname)
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(networkACL)
}
// Delete a network
// Will stop you if there's any nodes associated
func deleteNetwork(w http.ResponseWriter, r *http.Request) {

View file

@ -34,7 +34,6 @@ func nodeHandlers(r *mux.Router) {
r.HandleFunc("/api/nodes/{network}", createNode).Methods("POST")
r.HandleFunc("/api/nodes/adm/{network}/lastmodified", authorize(true, "network", http.HandlerFunc(getLastModified))).Methods("GET")
r.HandleFunc("/api/nodes/adm/{network}/authenticate", authenticate).Methods("POST")
}
func authenticate(response http.ResponseWriter, request *http.Request) {

View file

@ -5,6 +5,8 @@ import (
"github.com/gravitl/netmaker/database"
"github.com/gravitl/netmaker/logic"
"github.com/gravitl/netmaker/logic/acls"
"github.com/gravitl/netmaker/logic/acls/nodeacls"
"github.com/gravitl/netmaker/models"
"github.com/stretchr/testify/assert"
)
@ -143,6 +145,72 @@ func TestValidateEgressGateway(t *testing.T) {
})
}
func TestNodeACLs(t *testing.T) {
deleteAllNodes()
node1 := models.Node{PublicKey: "DM5qhLAE20PG9BbfBCger+Ac9D2NDOwCtY1rbYDLf34=", Name: "testnode", Endpoint: "10.0.0.50", MacAddress: "01:02:03:04:05:06", Password: "password", Network: "skynet", OS: "linux"}
node2 := models.Node{PublicKey: "DM5qhLAE20FG7BbfBCger+Ac9D2NDOwCtY1rbYDXf14=", Name: "testnode", Endpoint: "10.0.0.100", MacAddress: "01:02:03:04:05:07", Password: "password", Network: "skynet", OS: "linux"}
logic.CreateNode(&node1)
logic.CreateNode(&node2)
t.Run("acls not present", func(t *testing.T) {
currentACL, err := nodeacls.FetchAllACLs(nodeacls.NetworkID(node1.Network))
assert.Nil(t, err)
assert.NotNil(t, currentACL)
node1ACL, err := nodeacls.FetchNodeACL(nodeacls.NetworkID(node1.Network), nodeacls.NodeID(node1.ID))
assert.Nil(t, err)
assert.NotNil(t, node1ACL)
assert.Equal(t, acls.Allowed, node1ACL[acls.AclID(node2.ID)])
})
t.Run("node acls exists after creates", func(t *testing.T) {
node1ACL, err := nodeacls.FetchNodeACL(nodeacls.NetworkID(node1.Network), nodeacls.NodeID(node1.ID))
assert.Nil(t, err)
assert.NotNil(t, node1ACL)
node2ACL, err := nodeacls.FetchNodeACL(nodeacls.NetworkID(node2.Network), nodeacls.NodeID(node2.ID))
assert.Nil(t, err)
assert.NotNil(t, node2ACL)
assert.Equal(t, acls.Allowed, node2ACL[acls.AclID(node1.ID)])
})
t.Run("node acls correct after fetch", func(t *testing.T) {
node1ACL, err := nodeacls.FetchNodeACL(nodeacls.NetworkID(node1.Network), nodeacls.NodeID(node1.ID))
assert.Nil(t, err)
assert.Equal(t, acls.Allowed, node1ACL[acls.AclID(node2.ID)])
})
t.Run("node acls correct after modify", func(t *testing.T) {
node1ACL, err := nodeacls.FetchNodeACL(nodeacls.NetworkID(node1.Network), nodeacls.NodeID(node1.ID))
assert.Nil(t, err)
assert.NotNil(t, node1ACL)
node2ACL, err := nodeacls.FetchNodeACL(nodeacls.NetworkID(node2.Network), nodeacls.NodeID(node2.ID))
assert.Nil(t, err)
assert.NotNil(t, node2ACL)
currentACL, err := nodeacls.DisallowNodes(nodeacls.NetworkID(node1.Network), nodeacls.NodeID(node1.ID), nodeacls.NodeID(node2.ID))
assert.Nil(t, err)
assert.Equal(t, acls.NotAllowed, currentACL[acls.AclID(node1.ID)][acls.AclID(node2.ID)])
assert.Equal(t, acls.NotAllowed, currentACL[acls.AclID(node2.ID)][acls.AclID(node1.ID)])
currentACL.Save(acls.ContainerID(node1.Network))
})
t.Run("node acls correct after add new node not allowed", func(t *testing.T) {
node3 := models.Node{PublicKey: "DM5qhLAE20FG7BbfBCger+Ac9D2NDOwCtY1rbYDXv24=", Name: "testnode3", Endpoint: "10.0.0.100", MacAddress: "01:02:03:04:05:07", Password: "password", Network: "skynet", OS: "linux"}
logic.CreateNode(&node3)
var currentACL, err = nodeacls.FetchAllACLs(nodeacls.NetworkID(node3.Network))
assert.Nil(t, err)
assert.NotNil(t, currentACL)
assert.Equal(t, acls.NotPresent, currentACL[acls.AclID(node1.ID)][acls.AclID(node3.ID)])
nodeACL, err := nodeacls.CreateNodeACL(nodeacls.NetworkID(node3.Network), nodeacls.NodeID(node3.ID), acls.NotAllowed)
assert.Nil(t, err)
nodeACL.Save(acls.ContainerID(node3.Network), acls.AclID(node3.ID))
currentACL, err = nodeacls.FetchAllACLs(nodeacls.NetworkID(node3.Network))
assert.Nil(t, err)
assert.Equal(t, acls.NotAllowed, currentACL[acls.AclID(node1.ID)][acls.AclID(node3.ID)])
assert.Equal(t, acls.NotAllowed, currentACL[acls.AclID(node2.ID)][acls.AclID(node3.ID)])
})
t.Run("node acls removed", func(t *testing.T) {
retNetworkACL, err := nodeacls.RemoveNodeACL(nodeacls.NetworkID(node1.Network), nodeacls.NodeID(node1.ID))
assert.Nil(t, err)
assert.NotNil(t, retNetworkACL)
assert.Equal(t, acls.NotPresent, retNetworkACL[acls.AclID(node2.ID)][acls.AclID(node1.ID)])
})
deleteAllNodes()
}
func deleteAllNodes() {
database.DeleteAllRecords(database.NODES_TABLE_NAME)
}

View file

@ -50,6 +50,9 @@ const DATABASE_FILENAME = "netmaker.db"
// GENERATED_TABLE_NAME - stores server generated k/v
const GENERATED_TABLE_NAME = "generated"
// NODE_ACLS_TABLE_NAME - stores the node ACL rules
const NODE_ACLS_TABLE_NAME = "nodeacls"
// == ERROR CONSTS ==
// NO_RECORD - no singular result found
@ -127,6 +130,7 @@ func createTables() {
createTable(SERVERCONF_TABLE_NAME)
createTable(SERVER_UUID_TABLE_NAME)
createTable(GENERATED_TABLE_NAME)
createTable(NODE_ACLS_TABLE_NAME)
}
func createTable(tableName string) error {

10
go.mod
View file

@ -4,7 +4,7 @@ go 1.17
require (
github.com/eclipse/paho.mqtt.golang v1.3.5
github.com/go-playground/validator/v10 v10.10.0
github.com/go-playground/validator/v10 v10.10.1
github.com/golang-jwt/jwt/v4 v4.3.0
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/uuid v1.3.0
@ -17,15 +17,15 @@ require (
github.com/stretchr/testify v1.7.0
github.com/txn2/txeh v1.3.0
github.com/urfave/cli/v2 v2.3.0
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985 // indirect
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e // indirect
golang.org/x/text v0.3.7-0.20210524175448-3115f89c4b99 // indirect
golang.org/x/text v0.3.7 // indirect
golang.zx2c4.com/wireguard v0.0.0-20210805125648-3957e9b9dd19 // indirect
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20210913210325-91d1988e44de
google.golang.org/genproto v0.0.0-20210201151548-94839c025ad4 // indirect
google.golang.org/grpc v1.44.0
google.golang.org/grpc v1.45.0
google.golang.org/protobuf v1.27.1
gopkg.in/ini.v1 v1.66.4
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b

20
go.sum
View file

@ -69,8 +69,8 @@ github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0=
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
github.com/go-playground/validator/v10 v10.10.1 h1:uA0+amWMiglNZKZ9FJRKUAe9U3RX91eVn1JYXMWt7ig=
github.com/go-playground/validator/v10 v10.10.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
@ -275,8 +275,8 @@ golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210503195802-e9a32991a82e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@ -304,8 +304,8 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
golang.org/x/net v0.0.0-20210504132125-bbd867fde50d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985 h1:4CSI6oo7cOjJKajidEljs9h+uP0rRZBPPPhcCbj5mw8=
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -355,8 +355,8 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7-0.20210524175448-3115f89c4b99 h1:ZEXtoJu1S0ie/EmdYnjY3CqaCCZxnldL+K1ftMITD2Q=
golang.org/x/text v0.3.7-0.20210524175448-3115f89c4b99/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@ -389,8 +389,8 @@ google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQ
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.44.0 h1:weqSxi/TMs1SqFRMHCtBgXRs8k3X39QIDEZ0pRcttUg=
google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M=
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=

124
logic/acls/common.go Normal file
View file

@ -0,0 +1,124 @@
package acls
import (
"encoding/json"
"github.com/gravitl/netmaker/database"
)
// == type functions ==
// ACL.Allow - allows access by ID in memory
func (acl ACL) Allow(ID AclID) {
acl[ID] = Allowed
}
// ACL.DisallowNode - disallows access by ID in memory
func (acl ACL) Disallow(ID AclID) {
acl[ID] = NotAllowed
}
// ACL.Remove - removes a node from a ACL in memory
func (acl ACL) Remove(ID AclID) {
delete(acl, ID)
}
// ACL.Update - updates a ACL in DB
func (acl ACL) Save(containerID ContainerID, ID AclID) (ACL, error) {
return upsertACL(containerID, ID, acl)
}
// ACL.IsAllowed - sees if ID is allowed in referring ACL
func (acl ACL) IsAllowed(ID AclID) bool {
return acl[ID] == Allowed
}
// ACLContainer.IsAllowed - returns if the current ACL container contains allowed ACLs between two IDs
func (aclContainer ACLContainer) IsAllowed(ID1, ID2 AclID) bool {
return aclContainer[ID1].IsAllowed(ID2) && aclContainer[ID2].IsAllowed(ID1)
}
// ACLContainer.UpdateACL - saves the state of a ACL in the ACLContainer in memory
func (aclContainer ACLContainer) UpdateACL(ID AclID, acl ACL) ACLContainer {
aclContainer[ID] = acl
return aclContainer
}
// ACLContainer.RemoveACL - removes the state of a ACL in the ACLContainer in memory
func (aclContainer ACLContainer) RemoveACL(ID AclID) ACLContainer {
delete(aclContainer, ID)
return aclContainer
}
// ACLContainer.ChangeAccess - changes the relationship between two nodes in memory
func (networkACL ACLContainer) ChangeAccess(ID1, ID2 AclID, value byte) {
networkACL[ID1][ID2] = value
networkACL[ID2][ID1] = value
}
// ACLContainer.Save - saves the state of a ACLContainer to the db
func (aclContainer ACLContainer) Save(containerID ContainerID) (ACLContainer, error) {
return upsertACLContainer(containerID, aclContainer)
}
// ACLContainer.New - saves the state of a ACLContainer to the db
func (aclContainer ACLContainer) New(containerID ContainerID) (ACLContainer, error) {
return upsertACLContainer(containerID, nil)
}
// ACLContainer.Get - saves the state of a ACLContainer to the db
func (aclContainer ACLContainer) Get(containerID ContainerID) (ACLContainer, error) {
return fetchACLContainer(containerID)
}
// == private ==
// fetchACLContainer - fetches all current rules in given ACL container
func fetchACLContainer(containerID ContainerID) (ACLContainer, error) {
aclJson, err := fetchACLContainerJson(ContainerID(containerID))
if err != nil {
return nil, err
}
var currentNetworkACL ACLContainer
if err := json.Unmarshal([]byte(aclJson), &currentNetworkACL); err != nil {
return nil, err
}
return currentNetworkACL, nil
}
// fetchACLContainerJson - fetch the current ACL of given container except in json string
func fetchACLContainerJson(containerID ContainerID) (ACLJson, error) {
currentACLs, err := database.FetchRecord(database.NODE_ACLS_TABLE_NAME, string(containerID))
if err != nil {
return ACLJson(""), err
}
return ACLJson(currentACLs), nil
}
// upsertACL - applies a ACL to the db, overwrites or creates
func upsertACL(containerID ContainerID, ID AclID, acl ACL) (ACL, error) {
currentNetACL, err := fetchACLContainer(containerID)
if err != nil {
return acl, err
}
currentNetACL[ID] = acl
_, err = upsertACLContainer(containerID, currentNetACL)
return acl, err
}
// upsertACLContainer - Inserts or updates a network ACL given the json string of the ACL and the container ID
// if nil, create it
func upsertACLContainer(containerID ContainerID, aclContainer ACLContainer) (ACLContainer, error) {
if aclContainer == nil {
aclContainer = make(ACLContainer)
}
return aclContainer, database.Insert(string(containerID), string(convertNetworkACLtoACLJson(aclContainer)), database.NODE_ACLS_TABLE_NAME)
}
func convertNetworkACLtoACLJson(networkACL ACLContainer) ACLJson {
data, err := json.Marshal(networkACL)
if err != nil {
return ""
}
return ACLJson(data)
}

View file

@ -0,0 +1,87 @@
package nodeacls
import (
"github.com/gravitl/netmaker/database"
"github.com/gravitl/netmaker/logic/acls"
)
// CreateNodeACL - inserts or updates a node ACL on given network and adds to state
func CreateNodeACL(networkID NetworkID, nodeID NodeID, defaultVal byte) (acls.ACL, error) {
if defaultVal != acls.NotAllowed && defaultVal != acls.Allowed {
defaultVal = acls.NotAllowed
}
var currentNetworkACL, err = FetchAllACLs(networkID)
if err != nil {
if database.IsEmptyRecord(err) {
currentNetworkACL, err = currentNetworkACL.New(acls.ContainerID(networkID))
if err != nil {
return nil, err
}
} else {
return nil, err
}
}
var newNodeACL = make(acls.ACL)
for existingNodeID := range currentNetworkACL {
currentNetworkACL[existingNodeID][acls.AclID(nodeID)] = defaultVal // set the old nodes to default value for new node
newNodeACL[existingNodeID] = defaultVal // set the old nodes in new node ACL to default value
}
currentNetworkACL[acls.AclID(nodeID)] = newNodeACL // append the new node's ACL
retNetworkACL, err := currentNetworkACL.Save(acls.ContainerID(networkID)) // insert into db
if err != nil {
return nil, err
}
return retNetworkACL[acls.AclID(nodeID)], nil
}
// AllowNode - allow access between two nodes in memory
func AllowNodes(networkID NetworkID, node1, node2 NodeID) (acls.ACLContainer, error) {
container, err := FetchAllACLs(networkID)
if err != nil {
return nil, err
}
container[acls.AclID(node1)].Allow(acls.AclID(node2))
container[acls.AclID(node2)].Allow(acls.AclID(node1))
return container, nil
}
// DisallowNodes - deny access between two nodes
func DisallowNodes(networkID NetworkID, node1, node2 NodeID) (acls.ACLContainer, error) {
container, err := FetchAllACLs(networkID)
if err != nil {
return nil, err
}
container[acls.AclID(node1)].Disallow(acls.AclID(node2))
container[acls.AclID(node2)].Disallow(acls.AclID(node1))
return container, nil
}
// UpdateNodeACL - updates a node's ACL in state
func UpdateNodeACL(networkID NetworkID, nodeID NodeID, acl acls.ACL) (acls.ACL, error) {
var currentNetworkACL, err = FetchAllACLs(networkID)
if err != nil {
return nil, err
}
currentNetworkACL[acls.AclID(nodeID)] = acl
return currentNetworkACL[acls.AclID(nodeID)].Save(acls.ContainerID(networkID), acls.AclID(nodeID))
}
// RemoveNodeACL - removes a specific Node's ACL, returns the NetworkACL and error
func RemoveNodeACL(networkID NetworkID, nodeID NodeID) (acls.ACLContainer, error) {
var currentNetworkACL, err = FetchAllACLs(networkID)
if err != nil {
return nil, err
}
for currentNodeID := range currentNetworkACL {
if NodeID(currentNodeID) != nodeID {
currentNetworkACL[currentNodeID].Remove(acls.AclID(nodeID))
}
}
delete(currentNetworkACL, acls.AclID(nodeID))
return currentNetworkACL.Save(acls.ContainerID(networkID))
}
// DeleteACLContainer - removes an ACLContainer state from db
func DeleteACLContainer(network NetworkID) error {
return database.DeleteRecord(database.NODE_ACLS_TABLE_NAME, string(network))
}

View file

@ -0,0 +1,53 @@
package nodeacls
import (
"encoding/json"
"fmt"
"github.com/gravitl/netmaker/logic/acls"
)
// AreNodesAllowed - checks if nodes are allowed to communicate in their network ACL
func AreNodesAllowed(networkID NetworkID, node1, node2 NodeID) bool {
var currentNetworkACL, err = FetchAllACLs(networkID)
if err != nil {
return false
}
return currentNetworkACL[acls.AclID(node1)].IsAllowed(acls.AclID(node2)) && currentNetworkACL[acls.AclID(node2)].IsAllowed(acls.AclID(node1))
}
// FetchNodeACL - fetches a specific node's ACL in a given network
func FetchNodeACL(networkID NetworkID, nodeID NodeID) (acls.ACL, error) {
var currentNetworkACL, err = FetchAllACLs(networkID)
if err != nil {
return nil, err
}
if currentNetworkACL[acls.AclID(nodeID)] == nil {
return nil, fmt.Errorf("no node ACL present for node %s", nodeID)
}
return currentNetworkACL[acls.AclID(nodeID)], nil
}
// FetchNodeACLJson - fetches a node's acl in given network except returns the json string
func FetchNodeACLJson(networkID NetworkID, nodeID NodeID) (acls.ACLJson, error) {
currentNodeACL, err := FetchNodeACL(networkID, nodeID)
if err != nil {
return "", err
}
jsonData, err := json.Marshal(&currentNodeACL)
if err != nil {
return "", err
}
return acls.ACLJson(jsonData), nil
}
// FetchAllACLs - fetchs all node
func FetchAllACLs(networkID NetworkID) (acls.ACLContainer, error) {
var err error
var currentNetworkACL acls.ACLContainer
currentNetworkACL, err = currentNetworkACL.Get(acls.ContainerID(networkID))
if err != nil {
return nil, err
}
return currentNetworkACL, nil
}

View file

@ -0,0 +1,14 @@
package nodeacls
import (
"github.com/gravitl/netmaker/logic/acls"
)
type (
// NodeACL - interface for NodeACLs
NodeACL acls.ACL
// NodeID - node ID for ACLs
NodeID acls.AclID
// NetworkID - ACL container based on network ID for nodes
NetworkID acls.ContainerID
)

27
logic/acls/types.go Normal file
View file

@ -0,0 +1,27 @@
package acls
var (
// NotPresent - 0 - not present (default)
NotPresent = byte(0)
// NotAllowed - 1 - not allowed access
NotAllowed = byte(1) // 1 - not allowed
// Allowed - 2 - allowed access
Allowed = byte(2)
)
type (
// AclID - the node id of a given node
AclID string
// ACL - the ACL of other nodes in a NetworkACL for a single unique node
ACL map[AclID]byte
// ACLJson - the string representation in JSON of an ACL Node or Network
ACLJson string
// ContainerID - the networkID of a given network
ContainerID string
// ACLContainer - the total list of all node's ACL in a given network
ACLContainer map[AclID]ACL
)

View file

@ -33,7 +33,7 @@ func GetExtPeersList(node *models.Node) ([]models.ExtPeersResponse, error) {
logger.Log(2, "failed to unmarshal ext client")
continue
}
if extClient.Network == node.Network && extClient.IngressGatewayID == node.ID {
if extClient.Enabled && extClient.Network == node.Network && extClient.IngressGatewayID == node.ID {
peers = append(peers, peer)
}
}
@ -133,6 +133,14 @@ func CreateExtClient(extclient *models.ExtClient) error {
extclient.Address = newAddress
}
if extclient.Address6 == "" {
addr6, err := UniqueAddress6(extclient.Network)
if err != nil {
return err
}
extclient.Address6 = addr6
}
if extclient.ClientID == "" {
extclient.ClientID = models.GenerateNodeName()
}
@ -150,18 +158,18 @@ func CreateExtClient(extclient *models.ExtClient) error {
if err = database.Insert(key, string(data), database.EXT_CLIENT_TABLE_NAME); err != nil {
return err
}
err = SetNetworkNodesLastModified(extclient.Network)
return err
return SetNetworkNodesLastModified(extclient.Network)
}
// UpdateExtClient - only supports name changes right now
func UpdateExtClient(newclientid string, network string, client *models.ExtClient) (*models.ExtClient, error) {
func UpdateExtClient(newclientid string, network string, enabled bool, client *models.ExtClient) (*models.ExtClient, error) {
err := DeleteExtClient(network, client.ClientID)
if err != nil {
return client, err
}
client.ClientID = newclientid
client.Enabled = enabled
CreateExtClient(client)
return client, err
}

View file

@ -12,6 +12,7 @@ import (
"github.com/go-playground/validator/v10"
"github.com/gravitl/netmaker/database"
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/logic/acls/nodeacls"
"github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/netclient/ncutils"
"github.com/gravitl/netmaker/validation"
@ -41,6 +42,11 @@ func GetNetworks() ([]models.Network, error) {
// DeleteNetwork - deletes a network
func DeleteNetwork(network string) error {
// remove ACL for network
err := nodeacls.DeleteACLContainer(nodeacls.NetworkID(network))
if err != nil {
logger.Log(1, "failed to remove the node acls during network delete for network,", network)
}
nodeCount, err := GetNetworkNonServerNodeCount(network)
if nodeCount == 0 || database.IsEmptyRecord(err) {
// delete server nodes first then db records

View file

@ -12,6 +12,8 @@ import (
"github.com/google/uuid"
"github.com/gravitl/netmaker/database"
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/logic/acls"
"github.com/gravitl/netmaker/logic/acls/nodeacls"
"github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/netclient/ncutils"
"github.com/gravitl/netmaker/servercfg"
@ -174,6 +176,41 @@ func UpdateNode(currentNode *models.Node, newNode *models.Node) error {
return fmt.Errorf("failed to update node " + currentNode.ID + ", cannot change ID.")
}
// DeleteNodeByID - deletes a node from database or moves into delete nodes table
func DeleteNodeByID(node *models.Node, exterminate bool) error {
var err error
var key = node.ID
if !exterminate {
node.Action = models.NODE_DELETE
nodedata, err := json.Marshal(&node)
if err != nil {
return err
}
err = database.Insert(key, string(nodedata), database.DELETED_NODES_TABLE_NAME)
if err != nil {
return err
}
} else {
if err := database.DeleteRecord(database.DELETED_NODES_TABLE_NAME, key); err != nil {
logger.Log(2, err.Error())
}
}
if err = database.DeleteRecord(database.NODES_TABLE_NAME, key); err != nil {
return err
}
if servercfg.IsDNSMode() {
SetDNS()
}
_, err = nodeacls.RemoveNodeACL(nodeacls.NetworkID(node.Network), nodeacls.NodeID(node.ID))
if err != nil {
// ignoring for now, could hit a nil pointer if delete called twice
logger.Log(2, "attempted to remove node ACL for node", node.Name, node.ID)
}
return removeLocalServer(node)
}
// IsNodeIDUnique - checks if node id is unique
func IsNodeIDUnique(node *models.Node) (bool, error) {
_, err := database.FetchRecord(database.NODES_TABLE_NAME, node.ID)
@ -274,6 +311,13 @@ func CreateNode(node *models.Node) error {
if err != nil {
return err
}
// TODO get template logic to decide initial ACL value
_, err = nodeacls.CreateNodeACL(nodeacls.NetworkID(node.Network), nodeacls.NodeID(node.ID), acls.Allowed)
if err != nil {
logger.Log(1, "failed to create node ACL for node,", node.ID, "err:", err.Error())
return err
}
if node.IsPending != "yes" {
DecrimentKey(node.Network, node.AccessKey)
}

View file

@ -1,15 +1,17 @@
package logic
import (
"fmt"
"log"
"net"
"os"
"strconv"
"strings"
"time"
"github.com/gravitl/netmaker/database"
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/logic/acls"
"github.com/gravitl/netmaker/logic/acls/nodeacls"
"github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/netclient/ncutils"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
@ -33,7 +35,7 @@ func GetHubPeer(networkName string) []models.Node {
*/
// GetNodePeers - fetches peers for a given node
func GetNodePeers(networkName string, excludeRelayed bool, isP2S bool) ([]models.Node, error) {
func GetNodePeers(networkName, nodeid string, excludeRelayed bool, isP2S bool) ([]models.Node, error) {
var peers []models.Node
var networkNodes, egressNetworkNodes, err = getNetworkEgressAndNodes(networkName)
if err != nil {
@ -45,7 +47,16 @@ func GetNodePeers(networkName string, excludeRelayed bool, isP2S bool) ([]models
logger.Log(2, errN.Error())
}
currentNetworkACLs, aclErr := nodeacls.FetchAllACLs(nodeacls.NetworkID(networkName))
if aclErr != nil {
return peers, aclErr
}
for _, node := range networkNodes {
if !currentNetworkACLs.IsAllowed(acls.AclID(nodeid), acls.AclID(node.ID)) {
continue
}
var peer = models.Node{}
if node.IsEgressGateway == "yes" { // handle egress stuff
peer.EgressGatewayRanges = node.EgressGatewayRanges
@ -79,7 +90,7 @@ func GetNodePeers(networkName string, excludeRelayed bool, isP2S bool) ([]models
}
}
}
if !isP2S || peer.IsHub == "yes" {
if (!isP2S || peer.IsHub == "yes") && currentNetworkACLs.IsAllowed(acls.AclID(nodeid), acls.AclID(node.ID)) {
peers = append(peers, peer)
}
}
@ -107,7 +118,7 @@ func GetPeersList(refnode *models.Node) ([]models.Node, error) {
isP2S = true
}
if relayedNodeAddr == "" {
peers, err = GetNodePeers(networkName, excludeRelayed, isP2S)
peers, err = GetNodePeers(networkName, refnode.ID, excludeRelayed, isP2S)
} else {
var relayNode models.Node
relayNode, err = GetNodeRelay(networkName, relayedNodeAddr)
@ -127,7 +138,7 @@ func GetPeersList(refnode *models.Node) ([]models.Node, error) {
} else {
peerNode.AllowedIPs = append(peerNode.AllowedIPs, peerNode.RelayAddrs...)
}
nodepeers, err := GetNodePeers(networkName, false, isP2S)
nodepeers, err := GetNodePeers(networkName, refnode.ID, false, isP2S)
if err == nil && peerNode.UDPHolePunch == "yes" {
for _, nodepeer := range nodepeers {
if nodepeer.Address == peerNode.Address {
@ -165,11 +176,13 @@ func GetPeerUpdate(node *models.Node) (models.PeerUpdate, error) {
// #1 Set Keepalive values: set_keepalive
// #2 Set local address: set_local - could be a LOT BETTER and fix some bugs with additional logic
// #3 Set allowedips: set_allowedips
var dns string
for _, peer := range currentPeers {
if peer.ID == node.ID {
//skip yourself
continue
}
dns = dns + fmt.Sprintf("%s %s.%s\n", peer.Address, peer.Name, peer.Network)
pubkey, err := wgtypes.ParseKey(peer.PublicKey)
if err != nil {
return models.PeerUpdate{}, err
@ -225,12 +238,7 @@ func GetPeerUpdate(node *models.Node) (models.PeerUpdate, error) {
*/
dns, err := os.ReadFile("./config/dnsconfig/netmaker.hosts")
if err != nil {
logger.Log(0, "failed to read netmaker.hosts", err.Error())
} else {
peerUpdate.DNS = dns
}
peerUpdate.DNS = dns
return peerUpdate, nil
}

View file

@ -11,6 +11,8 @@ import (
"time"
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/logic/acls"
"github.com/gravitl/netmaker/logic/acls/nodeacls"
"github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/netclient/ncutils"
"github.com/gravitl/netmaker/servercfg"
@ -208,6 +210,11 @@ func GetServerPeers(serverNode *models.Node) ([]wgtypes.PeerConfig, bool, []stri
return nil, hasGateway, gateways, err
}
currentNetworkACL, err := nodeacls.FetchAllACLs(nodeacls.NetworkID(serverNode.Network))
if err != nil {
logger.Log(1, "could not fetch current ACL list, proceeding with all peers")
}
for _, node := range nodes {
pubkey, err := wgtypes.ParseKey(node.PublicKey)
if err != nil {
@ -225,6 +232,9 @@ func GetServerPeers(serverNode *models.Node) ([]wgtypes.PeerConfig, bool, []stri
continue
}
}
if currentNetworkACL != nil && currentNetworkACL.IsAllowed(acls.AclID(serverNode.ID), acls.AclID(node.ID)) {
continue
}
var peer wgtypes.PeerConfig
var peeraddr = net.IPNet{
@ -290,6 +300,7 @@ func GetServerPeers(serverNode *models.Node) ([]wgtypes.PeerConfig, bool, []stri
ReplaceAllowedIPs: true,
AllowedIPs: allowedips,
}
peers = append(peers, peer)
}
if serverNode.IsIngressGateway == "yes" {

View file

@ -17,7 +17,6 @@ import (
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/netclient/ncutils"
"github.com/gravitl/netmaker/servercfg"
)
// IsBase64 - checks if a string is in base64 format
@ -101,34 +100,6 @@ func GenerateCryptoString(n int) (string, error) {
return string(ret), nil
}
// DeleteNodeByID - deletes a node from database or moves into delete nodes table
func DeleteNodeByID(node *models.Node, exterminate bool) error {
var err error
var key = node.ID
if !exterminate {
node.Action = models.NODE_DELETE
nodedata, err := json.Marshal(&node)
if err != nil {
return err
}
err = database.Insert(key, string(nodedata), database.DELETED_NODES_TABLE_NAME)
if err != nil {
return err
}
} else {
if err := database.DeleteRecord(database.DELETED_NODES_TABLE_NAME, key); err != nil {
logger.Log(2, err.Error())
}
}
if err = database.DeleteRecord(database.NODES_TABLE_NAME, key); err != nil {
return err
}
if servercfg.IsDNSMode() {
SetDNS()
}
return removeLocalServer(node)
}
// RandomString - returns a random string in a charset
func RandomString(length int) string {
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
@ -181,6 +152,7 @@ func setPeerInfo(node *models.Node) models.Node {
peer.PublicKey = node.PublicKey
peer.Endpoint = node.Endpoint
peer.Name = node.Name
peer.Network = node.Network
peer.LocalAddress = node.LocalAddress
peer.ListenPort = node.ListenPort
peer.AllowedIPs = node.AllowedIPs

View file

@ -66,6 +66,11 @@ func initialize() { // Client Mode Prereq Check
logger.Log(0, "no OAuth provider found or not configured, continuing without OAuth")
}
err = serverctl.SetDefaultACLS()
if err != nil {
logger.FatalLog("error setting default acls: ", err.Error())
}
if servercfg.IsClientMode() != "off" {
output, err := ncutils.RunCmd("id -u", true)
if err != nil {

View file

@ -8,7 +8,9 @@ type ExtClient struct {
PublicKey string `json:"publickey" bson:"publickey"`
Network string `json:"network" bson:"network"`
Address string `json:"address" bson:"address"`
Address6 string `json:"address6" bson:"address6"`
IngressGatewayID string `json:"ingressgatewayid" bson:"ingressgatewayid"`
IngressGatewayEndpoint string `json:"ingressgatewayendpoint" bson:"ingressgatewayendpoint"`
LastModified int64 `json:"lastmodified" bson:"lastmodified"`
Enabled bool `json:"enabled" bson:"enabled"`
}

View file

@ -7,7 +7,7 @@ type PeerUpdate struct {
Network string `json:"network" bson:"network" yaml:"network"`
ServerAddrs []ServerAddr `json:"serveraddrs" bson:"serveraddrs" yaml:"serveraddrs"`
Peers []wgtypes.PeerConfig `json:"peers" bson:"peers" yaml:"peers"`
DNS []byte `json:"dns" bson:'dns" yaml:"dns"`
DNS string `json:"dns" bson:"dns" yaml:"dns"`
}
// KeyUpdate - key update struct

View file

@ -0,0 +1,15 @@
[Unit]
Description=Netclient Daemon
Documentation=https://docs.netmaker.org https://k8s.netmaker.org
After=network-online.target
Wants=network-online.target systemd-networkd-wait-online.service
[Service]
User=root
Type=simple
ExecStart=/sbin/netclient daemon
Restart=on-failure
RestartSec=15s
[Install]
WantedBy=multi-user.target

View file

@ -3,13 +3,11 @@ package functions
import (
"encoding/json"
"fmt"
"os"
"runtime"
"strings"
"time"
mqtt "github.com/eclipse/paho.mqtt.golang"
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/netclient/config"
"github.com/gravitl/netmaker/netclient/local"
@ -143,7 +141,7 @@ func NodeUpdate(client mqtt.Client, msg mqtt.Message) {
//deal with DNS
if newNode.DNSOn != "yes" && shouldDNSChange && nodeCfg.Node.Interface != "" {
ncutils.Log("settng DNS off")
if err := removeHostDNS(ncutils.IsWindows()); err != nil {
if err := removeHostDNS(nodeCfg.Network, ncutils.IsWindows()); err != nil {
ncutils.Log("error removing netmaker profile from /etc/hosts " + err.Error())
}
// _, err := ncutils.RunCmd("/usr/bin/resolvectl revert "+nodeCfg.Node.Interface, true)
@ -197,36 +195,30 @@ func UpdatePeers(client mqtt.Client, msg mqtt.Message) {
ncutils.Log("error syncing wg after peer update: " + err.Error())
return
}
logger.Log(0, "DNS updating /etc/hosts")
ncutils.Log("received peer update for node " + cfg.Node.Name + " " + cfg.Node.Network)
//skip dns updates if this is a peer update for comms network
if cfg.Node.NetworkSettings.IsComms == "yes" {
return
}
if cfg.Node.DNSOn == "yes" {
if err := setHostDNS(peerUpdate.DNS, ncutils.IsWindows()); err != nil {
if err := setHostDNS(peerUpdate.DNS, cfg.Node.Network, ncutils.IsWindows()); err != nil {
ncutils.Log("error updating /etc/hosts " + err.Error())
return
}
} else {
if err := removeHostDNS(ncutils.IsWindows()); err != nil {
ncutils.Log("error removing netmaker profile from /etc/hosts " + err.Error())
if err := removeHostDNS(cfg.Node.Network, ncutils.IsWindows()); err != nil {
ncutils.Log("error removing profile from /etc/hosts " + err.Error())
return
}
}
}
func setHostDNS(dns []byte, windows bool) error {
func setHostDNS(dns, network string, windows bool) error {
etchosts := "/etc/hosts"
if windows {
etchosts = "c:\\windows\\system32\\drivers\\etc\\hosts"
}
tmpfile := "/tmp/dnsdata"
if windows {
tmpfile = "c:\\windows\\temp\\dnsdata"
}
if err := os.WriteFile(tmpfile, dns, 0600); err != nil {
return err
}
dnsdata, err := os.Open(tmpfile)
if err != nil {
return err
}
dnsdata := strings.NewReader(dns)
profile, err := parser.ParseProfile(dnsdata)
if err != nil {
return err
@ -235,7 +227,7 @@ func setHostDNS(dns []byte, windows bool) error {
if err != nil {
return err
}
profile.Name = "netmaker"
profile.Name = network
profile.Status = types.Enabled
if err := hosts.ReplaceProfile(profile); err != nil {
return err
@ -246,7 +238,7 @@ func setHostDNS(dns []byte, windows bool) error {
return nil
}
func removeHostDNS(windows bool) error {
func removeHostDNS(network string, windows bool) error {
etchosts := "/etc/hosts"
if windows {
etchosts = "c:\\windows\\system32\\drivers\\etc\\hosts"
@ -255,7 +247,7 @@ func removeHostDNS(windows bool) error {
if err != nil {
return err
}
if err := hosts.RemoveProfile("netmaker"); err != nil {
if err := hosts.RemoveProfile(network); err != nil {
return err
}
if err := hosts.Flush(); err != nil {

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="0.11.1.0"
version="0.12.0.0"
processorArchitecture="*"
name="netclient.exe"
type="win32"

View file

@ -29,7 +29,7 @@
"OriginalFilename": "",
"PrivateBuild": "",
"ProductName": "Netclient",
"ProductVersion": "v0.11.1.0",
"ProductVersion": "v0.12.0.0",
"SpecialBuild": ""
},
"VarFileInfo": {

View file

@ -166,21 +166,7 @@ func InitWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig
}
}
// ensure you clear any existing interface first
d, _ := wgclient.Device(deviceiface)
startTime := time.Now()
for d != nil && d.Name == deviceiface {
if err = RemoveConf(deviceiface, false); err != nil { // remove interface first
if strings.Contains(err.Error(), "does not exist") {
err = nil
break
}
}
time.Sleep(time.Second >> 2)
d, _ = wgclient.Device(deviceiface)
if time.Now().After(startTime.Add(time.Second << 4)) {
break
}
}
RemoveConfGraceful(deviceiface)
ApplyConf(node, ifacename, confPath) // Apply initially
ncutils.PrintLog("waiting for interface...", 1) // ensure interface is created
output, _ := ncutils.RunCmd("wg", false)
@ -301,6 +287,7 @@ func ApplyConf(node *models.Node, ifacename string, confPath string) error {
var err error
switch os {
case "windows":
RemoveConfGraceful(ifacename)
ApplyWindowsConf(confPath)
case "darwin":
ApplyMacOSConf(node, ifacename, confPath)
@ -478,3 +465,29 @@ func UpdatePrivateKey(file, privateKey string) error {
}
return nil
}
// RemoveConfGraceful - Run remove conf and wait for it to actually be gone before proceeding
func RemoveConfGraceful(ifacename string) {
// ensure you clear any existing interface first
wgclient, err := wgctrl.New()
if err != nil {
ncutils.PrintLog("could not create wgclient", 0)
return
}
defer wgclient.Close()
d, _ := wgclient.Device(ifacename)
startTime := time.Now()
for d != nil && d.Name == ifacename {
if err = RemoveConf(ifacename, false); err != nil { // remove interface first
if strings.Contains(err.Error(), "does not exist") {
err = nil
break
}
}
time.Sleep(time.Second >> 2)
d, _ = wgclient.Device(ifacename)
if time.Now().After(startTime.Add(time.Second << 4)) {
break
}
}
}

View file

@ -7,7 +7,6 @@ import (
"strconv"
"strings"
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/netclient/config"
"github.com/gravitl/netmaker/netclient/ncutils"
@ -72,7 +71,7 @@ func ApplyWithoutWGQuick(node *models.Node, ifacename string, confPath string) e
}
}
if _, err := ncutils.RunCmd(ipExec+" link set down dev "+ifacename, false); err != nil {
logger.Log(2, "attempted to remove interface before editing")
ncutils.PrintLog("attempted to remove interface before editing", 1)
return err
}
if node.PostDown != "" {
@ -81,7 +80,7 @@ func ApplyWithoutWGQuick(node *models.Node, ifacename string, confPath string) e
}
// set MTU of node interface
if _, err := ncutils.RunCmd(ipExec+" link set mtu "+strconv.Itoa(int(node.MTU))+" up dev "+ifacename, true); err != nil {
logger.Log(2, "failed to create interface with mtu", strconv.Itoa(int(node.MTU)), "-", ifacename)
ncutils.PrintLog("failed to create interface with mtu "+strconv.Itoa(int(node.MTU))+"-"+ifacename, 1)
return err
}
if node.PostUp != "" {
@ -89,7 +88,7 @@ func ApplyWithoutWGQuick(node *models.Node, ifacename string, confPath string) e
_ = ncutils.RunCmds(runcmds, true)
}
if node.Address6 != "" && node.IsDualStack == "yes" {
logger.Log(1, "adding address:", node.Address6)
ncutils.PrintLog("adding address: "+node.Address6, 1)
_, _ = ncutils.RunCmd(ipExec+" address add dev "+ifacename+" "+node.Address6+"/64", true)
}
return nil
@ -104,8 +103,8 @@ func RemoveWithoutWGQuick(ifacename string) error {
out, err := ncutils.RunCmd(ipExec+" link del "+ifacename, false)
dontprint := strings.Contains(out, "does not exist") || strings.Contains(out, "Cannot find device")
if err != nil && !dontprint {
logger.Log(1, "error running command:", ipExec, "link del", ifacename)
logger.Log(1, out)
ncutils.PrintLog("error running command: "+ipExec+" link del "+ifacename, 1)
ncutils.PrintLog(out, 1)
}
network := strings.ReplaceAll(ifacename, "nm-", "")
nodeconf, err := config.ReadConfig(network)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View file

@ -10,6 +10,8 @@ import (
"github.com/gravitl/netmaker/database"
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/logic"
"github.com/gravitl/netmaker/logic/acls"
"github.com/gravitl/netmaker/logic/acls/nodeacls"
"github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/netclient/ncutils"
"github.com/gravitl/netmaker/servercfg"
@ -144,3 +146,21 @@ func SyncServerNetwork(network string) error {
*/
return nil
}
// SetDefaultACLS - runs through each network to see if ACL's are set. If not, goes through each node in network and adds the default ACL
func SetDefaultACLS() error {
// upgraded systems will not have ACL's set, which is why we need this function
nodes, err := logic.GetAllNodes()
if err != nil {
return err
}
for i := range nodes {
currentNodeACL, err := nodeacls.FetchNodeACL(nodeacls.NetworkID(nodes[i].Network), nodeacls.NodeID(nodes[i].ID))
if (err != nil && (database.IsEmptyRecord(err) || strings.Contains(err.Error(), "no node ACL present"))) || currentNodeACL == nil {
if _, err = nodeacls.CreateNodeACL(nodeacls.NetworkID(nodes[i].Network), nodeacls.NodeID(nodes[i].ID), acls.Allowed); err != nil {
logger.Log(1, "could not create a default ACL for node", nodes[i].ID)
}
}
}
return nil
}