From 85e2a8587b25aa2009ef3fb72fe1d883e8b34731 Mon Sep 17 00:00:00 2001 From: Markus Pesch Date: Thu, 10 Jun 2021 13:08:56 +0200 Subject: [PATCH] Initial Commit --- .editorconfig | 15 ++++++ .gitignore | 1 + .golangci.yml | 29 ++++++++++++ Dockerfile | 32 +++++++++++++ LICENSE | 13 ++++++ Makefile | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 8 ++++ go.mod | 3 ++ main.go | 44 ++++++++++++++++++ 9 files changed, 271 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .golangci.yml create mode 100644 Dockerfile create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.md create mode 100644 go.mod create mode 100644 main.go diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..dd69de0 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = false + +[Makefile] +indent_style = tab \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0d5aed1 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +getidev \ No newline at end of file diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..78a7d8a --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,29 @@ +run: + skip-dirs: + - it + timeout: 10m + tests: true + +linters: + disable-all: true + enable: + # Default + - deadcode + - errcheck + - gosimple + - govet + - ineffassign + - staticcheck + - structcheck + - typecheck + - unused + - varcheck + + # Additionally linters + - bodyclose + - misspell + - nilerr + - rowserrcheck + - sqlclosecheck + - unparam + - whitespace \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..6b0434c --- /dev/null +++ b/Dockerfile @@ -0,0 +1,32 @@ +ARG BASE_IMAGE +ARG BUILD_IMAGE + +# BUILD +# ===================================================================== +FROM ${BUILD_IMAGE} AS build + +ARG GONOPROXY +ARG GONOSUMDB +ARG GOPRIVATE +ARG GOPROXY +ARG GOSUMDB +ARG VERSION + +COPY ./ /workspace + +RUN cd /workspace && \ + GONOPROXY=${GONOPROXY} \ + GONOSUMDB=${GONOSUMDB} \ + GOPRIVATE=${GOPRIVATE} \ + GOPROXY=${GOPROXY} \ + GOSUMDB=${GOSUMDB} \ + VERSION=${VERSION} \ + make all + +# TARGET +# ===================================================================== +FROM ${BASE_IMAGE} + +COPY --from=build /workspace/getidev /usr/bin/getidev + +ENTRYPOINT [ "/usr/bin/getidev" ] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5a82408 --- /dev/null +++ b/LICENSE @@ -0,0 +1,13 @@ +Copyright 2019 Markus Pesch + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1f55d4c --- /dev/null +++ b/Makefile @@ -0,0 +1,126 @@ +# VERSION +VERSION?=$(shell git describe --abbrev=0)+hash.$(shell git rev-parse --short HEAD) + +# CONTAINER_RUNTIME +CONTAINER_RUNTIME?=$(shell which docker) + +# BUILD_IMAGE +BUILD_IMAGE_REGISTRY_HOST?=docker.io +BUILD_IMAGE_NAMESPACE=library +BUILD_IMAGE_REPOSITORY=golang +BUILD_IMAGE_VERSION?=1.16 +BUILD_IMAGE_FULLY_QUALIFIED:=${BUILD_IMAGE_REGISTRY_HOST}/${BUILD_IMAGE_NAMESPACE}/${BUILD_IMAGE_REPOSITORY}:${BUILD_IMAGE_VERSION} + +# BASE_IMAGE +BASE_IMAGE_REGISTRY_HOST?=docker.io +BASE_IMAGE_NAMESPACE=library +BASE_IMAGE_REPOSITORY=busybox +BASE_IMAGE_VERSION?=latest +BASE_IMAGE_FULLY_QUALIFIED=${BASE_IMAGE_REGISTRY_HOST}/${BASE_IMAGE_NAMESPACE}/${BASE_IMAGE_REPOSITORY}:${BASE_IMAGE_VERSION} + +# CONTAINER_IMAGE +CONTAINER_IMAGE_REGISTRY_HOST?=docker.io +CONTAINER_IMAGE_NAMESPACE=volkerraschek +CONTAINER_IMAGE_REPOSITORY=getidev +CONTAINER_IMAGE_VERSION?=latest +CONTAINER_IMAGE_FULLY_QUALIFIED=${CONTAINER_IMAGE_REGISTRY_HOST}/${CONTAINER_IMAGE_NAMESPACE}/${CONTAINER_IMAGE_REPOSITORY}:${CONTAINER_IMAGE_VERSION} +CONTAINER_IMAGE_UNQUALIFIED=${CONTAINER_IMAGE_NAMESPACE}/${CONTAINER_IMAGE_REPOSITORY}:${CONTAINER_IMAGE_VERSION} + +# EXECUTABLES +# ============================================================================== +EXECUTABLE_TARGETS=getidev + +PHONY=all +all: clean ${EXECUTABLE_TARGETS} + +getidev: + GOPRIVATE=$(shell go env GOPRIVATE) \ + GOPROXY=$(shell go env GOPROXY) \ + GONOPROXY=$(shell go env GONOPROXY) \ + GONOSUMDB=$(shell go env GONOSUMDB) \ + GOSUMDB=$(shell go env GOSUMDB) \ + go build -tags netgo -ldflags "-X main.version=${VERSION}" -o ${@} main.go + +# CLEAN +# ============================================================================== +PHONY+=clean +clean: + rm --force --recursive $(shell pwd)/getidev* + +# GOLANGCI-LINT +# ============================================================================== +PHONY+=golangci-lint +golangci-lint: + golangci-lint run --concurrency=$(shell nproc) + +# GOSEC +# ============================================================================== +PHONY+=gosec +gosec: + gosec $(shell pwd)/... + +# CONTAINER-IMAGE +# ============================================================================== +PHONY+=container-image/build +container-image/build: + ${CONTAINER_RUNTIME} build \ + --build-arg BASE_IMAGE=${BASE_IMAGE_FULLY_QUALIFIED} \ + --build-arg BUILD_IMAGE=${BUILD_IMAGE_FULLY_QUALIFIED} \ + --build-arg GOPRIVATE=$(shell go env GOPRIVATE) \ + --build-arg GOPROXY=$(shell go env GOPROXY) \ + --build-arg GONOPROXY=$(shell go env GONOPROXY) \ + --build-arg GONOSUMDB=$(shell go env GONOSUMDB) \ + --build-arg GOSUMDB=$(shell go env GOSUMDB) \ + --build-arg VERSION=${VERSION} \ + --file ./Dockerfile \ + --no-cache \ + --tag ${CONTAINER_IMAGE_UNQUALIFIED} \ + --tag ${CONTAINER_IMAGE_FULLY_QUALIFIED} \ + . + +PHONY+=container-image/push +container-image/push: container-image/build + ${CONTAINER_RUNTIME} push ${CONTAINER_IMAGE_FULLY_QUALIFIED} + +# CONTAINER STEPS - EXECUTABLE +# ============================================================================== +PHONY+=container-run/all +container-run/all: + $(MAKE) container-run COMMAND=${@:container-run/%=%} + +PHONY+=${EXECUTABLE_TARGETS:%=container-run/%} +${EXECUTABLE_TARGETS:%=container-run/%}: + $(MAKE) container-run COMMAND=${@:container-run/%=%} + +# CONTAINER STEPS - CLEAN +# ============================================================================== +PHONY+=container-run/clean +container-run/clean: + $(MAKE) container-run COMMAND=${@:container-run/%=%} + +# GENERAL CONTAINER COMMAND +# ============================================================================== +PHONY+=container-run +container-run: + ${CONTAINER_RUNTIME} run \ + --env CONTAINER_IMAGE_VERSION=${CONTAINER_IMAGE_VERSION} \ + --env GONOPROXY=$(shell go env GONOPROXY) \ + --env GONOSUMDB=$(shell go env GONOSUMDB) \ + --env GOPRIVATE=$(shell go env GOPRIVATE) \ + --env GOPROXY=$(shell go env GOPROXY) \ + --env GOSUMDB=$(shell go env GOSUMDB) \ + --env VERSION=${VERSION} \ + --net=host \ + --rm \ + --volume /tmp:/tmp \ + --volume ${HOME}/go:/root/go \ + --volume $(shell pwd):/workspace \ + --workdir /workspace \ + ${BUILD_IMAGE_FULLY_QUALIFIED} \ + make ${COMMAND} + +# PHONY +# ============================================================================== +# Declare the contents of the PHONY variable as phony. We keep that information +# in a variable so we can use it in if_changed. +.PHONY: ${PHONY} diff --git a/README.md b/README.md new file mode 100644 index 0000000..6ced933 --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +# getidev + +`getidev` is a small programme to determine the network interface for an IP +address. + +`getidev` serves as an alternative to `ip route get | awk ...` because `ip +route get` can return different output depending on the environment and +therefore the construct is unsafe. diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..16f9e5c --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/volker-raschek/getidev + +go 1.16 diff --git a/main.go b/main.go new file mode 100644 index 0000000..d9c674e --- /dev/null +++ b/main.go @@ -0,0 +1,44 @@ +package main + +import ( + "fmt" + "log" + "net" + "os" + "strings" +) + +var version string + +func main() { + ips := os.Args[1:] + switch { + case len(ips) == 0: + log.Fatal("Expect at least one argument") + case len(ips) >= 2: + log.Fatal("Expect only one argument") + } + + ip := strings.Split(ips[0], "/")[0] + + interfaces, err := net.Interfaces() + if err != nil { + log.Fatal(err.Error()) + } + + for _, iface := range interfaces { + addrs, err := iface.Addrs() + if err != nil { + log.Fatal(err.Error()) + } + + for _, addr := range addrs { + if strings.Split(addr.String(), "/")[0] == ip { + fmt.Fprintln(os.Stdout, iface.Name) + return + } + } + } + + os.Exit(1) +}