Merge branch 'master' into release/2.4
This commit is contained in:
commit
64e3aff65b
98
environment/os/fedora-36.sh
Executable file
98
environment/os/fedora-36.sh
Executable file
@ -0,0 +1,98 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -Eeuo pipefail
|
||||||
|
|
||||||
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||||
|
source "$DIR/../util.sh"
|
||||||
|
|
||||||
|
check_operating_system "fedora-36"
|
||||||
|
check_architecture "x86_64"
|
||||||
|
|
||||||
|
TOOLCHAIN_BUILD_DEPS=(
|
||||||
|
coreutils-common gcc gcc-c++ make # generic build tools
|
||||||
|
wget # used for archive download
|
||||||
|
gnupg2 # used for archive signature verification
|
||||||
|
tar gzip bzip2 xz unzip # used for archive unpacking
|
||||||
|
zlib-devel # zlib library used for all builds
|
||||||
|
expat-devel xz-devel python3-devel texinfo libbabeltrace-devel # for gdb
|
||||||
|
curl libcurl-devel # for cmake
|
||||||
|
readline-devel # for cmake and llvm
|
||||||
|
libffi-devel libxml2-devel # for llvm
|
||||||
|
libedit-devel pcre-devel automake bison # for swig
|
||||||
|
file
|
||||||
|
openssl-devel
|
||||||
|
gmp-devel
|
||||||
|
gperf
|
||||||
|
diffutils
|
||||||
|
libipt libipt-devel # intel
|
||||||
|
patch
|
||||||
|
)
|
||||||
|
|
||||||
|
TOOLCHAIN_RUN_DEPS=(
|
||||||
|
make # generic build tools
|
||||||
|
tar gzip bzip2 xz # used for archive unpacking
|
||||||
|
zlib # zlib library used for all builds
|
||||||
|
expat xz-libs python3 # for gdb
|
||||||
|
readline # for cmake and llvm
|
||||||
|
libffi libxml2 # for llvm
|
||||||
|
openssl-devel
|
||||||
|
perl # for openssl
|
||||||
|
)
|
||||||
|
|
||||||
|
MEMGRAPH_BUILD_DEPS=(
|
||||||
|
git # source code control
|
||||||
|
make pkgconf-pkg-config # build system
|
||||||
|
wget # for downloading libs
|
||||||
|
libuuid-devel java-11-openjdk # required by antlr
|
||||||
|
readline-devel # for memgraph console
|
||||||
|
python3-devel # for query modules
|
||||||
|
openssl-devel
|
||||||
|
libseccomp-devel
|
||||||
|
python3 python3-pip python3-virtualenv python3-virtualenvwrapper python3-pyyaml nmap-ncat # for tests
|
||||||
|
libcurl-devel # mg-requests
|
||||||
|
rpm-build rpmlint # for RPM package building
|
||||||
|
doxygen graphviz # source documentation generators
|
||||||
|
which nodejs golang zip unzip java-11-openjdk-devel # for driver tests
|
||||||
|
sbcl # for custom Lisp C++ preprocessing
|
||||||
|
autoconf # for jemalloc code generation
|
||||||
|
libtool # for protobuf code generation
|
||||||
|
)
|
||||||
|
|
||||||
|
list() {
|
||||||
|
echo "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
check() {
|
||||||
|
local missing=""
|
||||||
|
for pkg in $1; do
|
||||||
|
if ! dnf list installed "$pkg" >/dev/null 2>/dev/null; then
|
||||||
|
missing="$pkg $missing"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [ "$missing" != "" ]; then
|
||||||
|
echo "MISSING PACKAGES: $missing"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
install() {
|
||||||
|
cd "$DIR"
|
||||||
|
if [ "$EUID" -ne 0 ]; then
|
||||||
|
echo "Please run as root."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# If GitHub Actions runner is installed, append LANG to the environment.
|
||||||
|
# Python related tests don't work without the LANG export.
|
||||||
|
if [ -d "/home/gh/actions-runner" ]; then
|
||||||
|
echo "LANG=en_US.utf8" >> /home/gh/actions-runner/.env
|
||||||
|
else
|
||||||
|
echo "NOTE: export LANG=en_US.utf8"
|
||||||
|
fi
|
||||||
|
dnf update -y
|
||||||
|
for pkg in $1; do
|
||||||
|
dnf install -y "$pkg"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
deps=$2"[*]"
|
||||||
|
"$1" "${!deps}"
|
1
environment/toolchain/.gitignore
vendored
Normal file
1
environment/toolchain/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
*.tar.gz
|
@ -10,6 +10,14 @@ cd "$DIR"
|
|||||||
source "$DIR/../util.sh"
|
source "$DIR/../util.sh"
|
||||||
DISTRO="$(operating_system)"
|
DISTRO="$(operating_system)"
|
||||||
|
|
||||||
|
function log_tool_name () {
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "#### $1 ####"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
for_arm=false
|
for_arm=false
|
||||||
if [[ "$#" -eq 1 ]]; then
|
if [[ "$#" -eq 1 ]]; then
|
||||||
if [[ "$1" == "--for-arm" ]]; then
|
if [[ "$1" == "--for-arm" ]]; then
|
||||||
@ -20,9 +28,11 @@ if [[ "$#" -eq 1 ]]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
os="$1"
|
TOOLCHAIN_STDCXX="${TOOLCHAIN_STDCXX:-libstdc++}"
|
||||||
|
if [[ "$TOOLCHAIN_STDCXX" != "libstdc++" && "$TOOLCHAIN_STDCXX" != "libc++" ]]; then
|
||||||
# toolchain version
|
echo "Only GCC (libstdc++) or LLVM (libc++) C++ standard library implementations are supported."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
TOOLCHAIN_VERSION=4
|
TOOLCHAIN_VERSION=4
|
||||||
|
|
||||||
# package versions used
|
# package versions used
|
||||||
@ -99,6 +109,8 @@ if [ ! -f llvm-$LLVM_VERSION.src.tar.xz ]; then
|
|||||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/clang-tools-extra-$LLVM_VERSION.src.tar.xz
|
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/clang-tools-extra-$LLVM_VERSION.src.tar.xz
|
||||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/compiler-rt-$LLVM_VERSION.src.tar.xz
|
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/compiler-rt-$LLVM_VERSION.src.tar.xz
|
||||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/libunwind-$LLVM_VERSION.src.tar.xz
|
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/libunwind-$LLVM_VERSION.src.tar.xz
|
||||||
|
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/libcxx-$LLVM_VERSION.src.tar.xz
|
||||||
|
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/libcxxabi-$LLVM_VERSION.src.tar.xz
|
||||||
fi
|
fi
|
||||||
if [ ! -f pahole-gdb-master.zip ]; then
|
if [ ! -f pahole-gdb-master.zip ]; then
|
||||||
wget https://github.com/PhilArmstrong/pahole-gdb/archive/master.zip -O pahole-gdb-master.zip
|
wget https://github.com/PhilArmstrong/pahole-gdb/archive/master.zip -O pahole-gdb-master.zip
|
||||||
@ -156,6 +168,8 @@ if [ ! -f llvm-$LLVM_VERSION.src.tar.xz.sig ]; then
|
|||||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/clang-tools-extra-$LLVM_VERSION.src.tar.xz.sig
|
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/clang-tools-extra-$LLVM_VERSION.src.tar.xz.sig
|
||||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/compiler-rt-$LLVM_VERSION.src.tar.xz.sig
|
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/compiler-rt-$LLVM_VERSION.src.tar.xz.sig
|
||||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/libunwind-$LLVM_VERSION.src.tar.xz.sig
|
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/libunwind-$LLVM_VERSION.src.tar.xz.sig
|
||||||
|
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/libcxx-$LLVM_VERSION.src.tar.xz.sig
|
||||||
|
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/libcxxabi-$LLVM_VERSION.src.tar.xz.sig
|
||||||
fi
|
fi
|
||||||
# list of valid llvm gnupg keys: https://releases.llvm.org/download.html
|
# list of valid llvm gnupg keys: https://releases.llvm.org/download.html
|
||||||
$GPG --keyserver $KEYSERVER --recv-keys 0x474E22316ABF4785A88C6E8EA2C794A986419D8A
|
$GPG --keyserver $KEYSERVER --recv-keys 0x474E22316ABF4785A88C6E8EA2C794A986419D8A
|
||||||
@ -165,6 +179,8 @@ $GPG --verify lld-$LLVM_VERSION.src.tar.xz.sig lld-$LLVM_VERSION.src.tar.xz
|
|||||||
$GPG --verify clang-tools-extra-$LLVM_VERSION.src.tar.xz.sig clang-tools-extra-$LLVM_VERSION.src.tar.xz
|
$GPG --verify clang-tools-extra-$LLVM_VERSION.src.tar.xz.sig clang-tools-extra-$LLVM_VERSION.src.tar.xz
|
||||||
$GPG --verify compiler-rt-$LLVM_VERSION.src.tar.xz.sig compiler-rt-$LLVM_VERSION.src.tar.xz
|
$GPG --verify compiler-rt-$LLVM_VERSION.src.tar.xz.sig compiler-rt-$LLVM_VERSION.src.tar.xz
|
||||||
$GPG --verify libunwind-$LLVM_VERSION.src.tar.xz.sig libunwind-$LLVM_VERSION.src.tar.xz
|
$GPG --verify libunwind-$LLVM_VERSION.src.tar.xz.sig libunwind-$LLVM_VERSION.src.tar.xz
|
||||||
|
$GPG --verify libcxx-$LLVM_VERSION.src.tar.xz.sig libcxx-$LLVM_VERSION.src.tar.xz
|
||||||
|
$GPG --verify libcxxabi-$LLVM_VERSION.src.tar.xz.sig libcxxabi-$LLVM_VERSION.src.tar.xz
|
||||||
|
|
||||||
popd
|
popd
|
||||||
|
|
||||||
@ -172,7 +188,7 @@ popd
|
|||||||
mkdir -p build
|
mkdir -p build
|
||||||
pushd build
|
pushd build
|
||||||
|
|
||||||
# compile gcc
|
log_tool_name "GCC $GCC_VERSION"
|
||||||
if [ ! -f $PREFIX/bin/gcc ]; then
|
if [ ! -f $PREFIX/bin/gcc ]; then
|
||||||
if [ -d gcc-$GCC_VERSION ]; then
|
if [ -d gcc-$GCC_VERSION ]; then
|
||||||
rm -rf gcc-$GCC_VERSION
|
rm -rf gcc-$GCC_VERSION
|
||||||
@ -263,7 +279,7 @@ fi
|
|||||||
export PATH=$PREFIX/bin:$PATH
|
export PATH=$PREFIX/bin:$PATH
|
||||||
export LD_LIBRARY_PATH=$PREFIX/lib64
|
export LD_LIBRARY_PATH=$PREFIX/lib64
|
||||||
|
|
||||||
# compile binutils
|
log_tool_name "binutils $BINUTILS_VERSION"
|
||||||
if [ ! -f $PREFIX/bin/ld.gold ]; then
|
if [ ! -f $PREFIX/bin/ld.gold ]; then
|
||||||
if [ -d binutils-$BINUTILS_VERSION ]; then
|
if [ -d binutils-$BINUTILS_VERSION ]; then
|
||||||
rm -rf binutils-$BINUTILS_VERSION
|
rm -rf binutils-$BINUTILS_VERSION
|
||||||
@ -327,7 +343,7 @@ if [ ! -f $PREFIX/bin/ld.gold ]; then
|
|||||||
popd && popd
|
popd && popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# compile gdb
|
log_tool_name "GDB $GDB_VERSION"
|
||||||
if [ ! -f $PREFIX/bin/gdb ]; then
|
if [ ! -f $PREFIX/bin/gdb ]; then
|
||||||
if [ -d gdb-$GDB_VERSION ]; then
|
if [ -d gdb-$GDB_VERSION ]; then
|
||||||
rm -rf gdb-$GDB_VERSION
|
rm -rf gdb-$GDB_VERSION
|
||||||
@ -398,13 +414,13 @@ if [ ! -f $PREFIX/bin/gdb ]; then
|
|||||||
popd && popd
|
popd && popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# install pahole
|
log_tool_name "install pahole"
|
||||||
if [ ! -d $PREFIX/share/pahole-gdb ]; then
|
if [ ! -d $PREFIX/share/pahole-gdb ]; then
|
||||||
unzip ../archives/pahole-gdb-master.zip
|
unzip ../archives/pahole-gdb-master.zip
|
||||||
mv pahole-gdb-master $PREFIX/share/pahole-gdb
|
mv pahole-gdb-master $PREFIX/share/pahole-gdb
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# setup system gdbinit
|
log_tool_name "setup system gdbinit"
|
||||||
if [ ! -f $PREFIX/etc/gdb/gdbinit ]; then
|
if [ ! -f $PREFIX/etc/gdb/gdbinit ]; then
|
||||||
mkdir -p $PREFIX/etc/gdb
|
mkdir -p $PREFIX/etc/gdb
|
||||||
cat >$PREFIX/etc/gdb/gdbinit <<EOF
|
cat >$PREFIX/etc/gdb/gdbinit <<EOF
|
||||||
@ -430,7 +446,7 @@ end
|
|||||||
EOF
|
EOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# compile cmake
|
log_tool_name "cmake $CMAKE_VERSION"
|
||||||
if [ ! -f $PREFIX/bin/cmake ]; then
|
if [ ! -f $PREFIX/bin/cmake ]; then
|
||||||
if [ -d cmake-$CMAKE_VERSION ]; then
|
if [ -d cmake-$CMAKE_VERSION ]; then
|
||||||
rm -rf cmake-$CMAKE_VERSION
|
rm -rf cmake-$CMAKE_VERSION
|
||||||
@ -456,7 +472,7 @@ if [ ! -f $PREFIX/bin/cmake ]; then
|
|||||||
popd && popd
|
popd && popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# compile cppcheck
|
log_tool_name "cppcheck $CPPCHECK_VERSION"
|
||||||
if [ ! -f $PREFIX/bin/cppcheck ]; then
|
if [ ! -f $PREFIX/bin/cppcheck ]; then
|
||||||
if [ -d cppcheck-$CPPCHECK_VERSION ]; then
|
if [ -d cppcheck-$CPPCHECK_VERSION ]; then
|
||||||
rm -rf cppcheck-$CPPCHECK_VERSION
|
rm -rf cppcheck-$CPPCHECK_VERSION
|
||||||
@ -480,7 +496,7 @@ if [ ! -f $PREFIX/bin/cppcheck ]; then
|
|||||||
popd
|
popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# compile swig
|
log_tool_name "swig $SWIG_VERSION"
|
||||||
if [ ! -d swig-$SWIG_VERSION/install ]; then
|
if [ ! -d swig-$SWIG_VERSION/install ]; then
|
||||||
if [ -d swig-$SWIG_VERSION ]; then
|
if [ -d swig-$SWIG_VERSION ]; then
|
||||||
rm -rf swig-$SWIG_VERSION
|
rm -rf swig-$SWIG_VERSION
|
||||||
@ -496,7 +512,7 @@ if [ ! -d swig-$SWIG_VERSION/install ]; then
|
|||||||
popd && popd
|
popd && popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# compile llvm
|
log_tool_name "LLVM $LLVM_VERSION"
|
||||||
if [ ! -f $PREFIX/bin/clang ]; then
|
if [ ! -f $PREFIX/bin/clang ]; then
|
||||||
if [ -d llvm-$LLVM_VERSION ]; then
|
if [ -d llvm-$LLVM_VERSION ]; then
|
||||||
rm -rf llvm-$LLVM_VERSION
|
rm -rf llvm-$LLVM_VERSION
|
||||||
@ -513,8 +529,19 @@ if [ ! -f $PREFIX/bin/clang ]; then
|
|||||||
mv compiler-rt-$LLVM_VERSION.src/ llvm-$LLVM_VERSION/projects/compiler-rt
|
mv compiler-rt-$LLVM_VERSION.src/ llvm-$LLVM_VERSION/projects/compiler-rt
|
||||||
tar -xvf ../archives/libunwind-$LLVM_VERSION.src.tar.xz
|
tar -xvf ../archives/libunwind-$LLVM_VERSION.src.tar.xz
|
||||||
mv libunwind-$LLVM_VERSION.src/include/mach-o llvm-$LLVM_VERSION/tools/lld/include
|
mv libunwind-$LLVM_VERSION.src/include/mach-o llvm-$LLVM_VERSION/tools/lld/include
|
||||||
|
|
||||||
|
# The following is required because of libc++
|
||||||
|
tar -xvf ../archives/libcxx-$LLVM_VERSION.src.tar.xz
|
||||||
|
mv libcxx-$LLVM_VERSION.src llvm-$LLVM_VERSION/projects/libcxx
|
||||||
|
tar -xvf ../archives/libcxxabi-$LLVM_VERSION.src.tar.xz
|
||||||
|
mv libcxxabi-$LLVM_VERSION.src llvm-$LLVM_VERSION/projects/libcxxabi
|
||||||
|
# NOTE: We moved part of the libunwind in one of the previous step.
|
||||||
|
rm -r libunwind-$LLVM_VERSION.src
|
||||||
|
tar -xvf ../archives/libunwind-$LLVM_VERSION.src.tar.xz
|
||||||
|
mv libunwind-$LLVM_VERSION.src llvm-$LLVM_VERSION/projects/libunwind
|
||||||
|
|
||||||
pushd llvm-$LLVM_VERSION
|
pushd llvm-$LLVM_VERSION
|
||||||
mkdir build && pushd build
|
mkdir -p build && pushd build
|
||||||
# activate swig
|
# activate swig
|
||||||
export PATH=$DIR/build/swig-$SWIG_VERSION/install/bin:$PATH
|
export PATH=$DIR/build/swig-$SWIG_VERSION/install/bin:$PATH
|
||||||
# influenced by: https://buildd.debian.org/status/fetch.php?pkg=llvm-toolchain-7&arch=amd64&ver=1%3A7.0.1%7E%2Brc2-1%7Eexp1&stamp=1541506173&raw=0
|
# influenced by: https://buildd.debian.org/status/fetch.php?pkg=llvm-toolchain-7&arch=amd64&ver=1%3A7.0.1%7E%2Brc2-1%7Eexp1&stamp=1541506173&raw=0
|
||||||
@ -820,7 +847,11 @@ source $PREFIX/activate
|
|||||||
export CC=$PREFIX/bin/clang
|
export CC=$PREFIX/bin/clang
|
||||||
export CXX=$PREFIX/bin/clang++
|
export CXX=$PREFIX/bin/clang++
|
||||||
export CFLAGS="$CFLAGS -fPIC"
|
export CFLAGS="$CFLAGS -fPIC"
|
||||||
export CXXFLAGS="$CXXFLAGS -fPIC"
|
if [ "$TOOLCHAIN_STDCXX" = "libstdc++" ]; then
|
||||||
|
export CXXFLAGS="$CXXFLAGS -fPIC"
|
||||||
|
else
|
||||||
|
export CXXFLAGS="$CXXFLAGS -fPIC -stdlib=libc++"
|
||||||
|
fi
|
||||||
COMMON_CMAKE_FLAGS="-DCMAKE_INSTALL_PREFIX=$PREFIX
|
COMMON_CMAKE_FLAGS="-DCMAKE_INSTALL_PREFIX=$PREFIX
|
||||||
-DCMAKE_PREFIX_PATH=$PREFIX
|
-DCMAKE_PREFIX_PATH=$PREFIX
|
||||||
-DCMAKE_BUILD_TYPE=Release
|
-DCMAKE_BUILD_TYPE=Release
|
||||||
@ -834,7 +865,7 @@ COMMON_CMAKE_FLAGS="-DCMAKE_INSTALL_PREFIX=$PREFIX
|
|||||||
COMMON_CONFIGURE_FLAGS="--enable-shared=no --prefix=$PREFIX"
|
COMMON_CONFIGURE_FLAGS="--enable-shared=no --prefix=$PREFIX"
|
||||||
COMMON_MAKE_INSTALL_FLAGS="-j$CPUS BUILD_SHARED=no PREFIX=$PREFIX install"
|
COMMON_MAKE_INSTALL_FLAGS="-j$CPUS BUILD_SHARED=no PREFIX=$PREFIX install"
|
||||||
|
|
||||||
# install bzip2
|
log_tool_name "bzip2 $BZIP2_VERSION"
|
||||||
if [ ! -f $PREFIX/include/bzlib.h ]; then
|
if [ ! -f $PREFIX/include/bzlib.h ]; then
|
||||||
if [ -d bzip2-$BZIP2_VERSION ]; then
|
if [ -d bzip2-$BZIP2_VERSION ]; then
|
||||||
rm -rf bzip2-$BZIP2_VERSION
|
rm -rf bzip2-$BZIP2_VERSION
|
||||||
@ -845,7 +876,7 @@ if [ ! -f $PREFIX/include/bzlib.h ]; then
|
|||||||
popd
|
popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# install fmt
|
log_tool_name "fmt $FMT_VERSION"
|
||||||
if [ ! -d $PREFIX/include/fmt ]; then
|
if [ ! -d $PREFIX/include/fmt ]; then
|
||||||
if [ -d fmt-$FMT_VERSION ]; then
|
if [ -d fmt-$FMT_VERSION ]; then
|
||||||
rm -rf fmt-$FMT_VERSION
|
rm -rf fmt-$FMT_VERSION
|
||||||
@ -858,7 +889,7 @@ if [ ! -d $PREFIX/include/fmt ]; then
|
|||||||
popd && popd
|
popd && popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# install lz4
|
log_tool_name "lz4 $LZ4_VERSION"
|
||||||
if [ ! -f $PREFIX/include/lz4.h ]; then
|
if [ ! -f $PREFIX/include/lz4.h ]; then
|
||||||
if [ -d lz4-$LZ4_VERSION ]; then
|
if [ -d lz4-$LZ4_VERSION ]; then
|
||||||
rm -rf lz4-$LZ4_VERSION
|
rm -rf lz4-$LZ4_VERSION
|
||||||
@ -869,7 +900,7 @@ if [ ! -f $PREFIX/include/lz4.h ]; then
|
|||||||
popd
|
popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# install xz
|
log_tool_name "xz $XZ_VERSION"
|
||||||
if [ ! -f $PREFIX/include/lzma.h ]; then
|
if [ ! -f $PREFIX/include/lzma.h ]; then
|
||||||
if [ -d xz-$XZ_VERSION ]; then
|
if [ -d xz-$XZ_VERSION ]; then
|
||||||
rm -rf xz-$XZ_VERSION
|
rm -rf xz-$XZ_VERSION
|
||||||
@ -881,7 +912,7 @@ if [ ! -f $PREFIX/include/lzma.h ]; then
|
|||||||
popd
|
popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# install zlib
|
log_tool_name "zlib $ZLIB_VERSION"
|
||||||
if [ ! -f $PREFIX/include/zlib.h ]; then
|
if [ ! -f $PREFIX/include/zlib.h ]; then
|
||||||
if [ -d zlib-$ZLIB_VERSION ]; then
|
if [ -d zlib-$ZLIB_VERSION ]; then
|
||||||
rm -rf zlib-$ZLIB_VERSION
|
rm -rf zlib-$ZLIB_VERSION
|
||||||
@ -895,7 +926,7 @@ if [ ! -f $PREFIX/include/zlib.h ]; then
|
|||||||
popd && popd
|
popd && popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# install zstd
|
log_tool_name "zstd $ZSTD_VERSION"
|
||||||
if [ ! -f $PREFIX/include/zstd.h ]; then
|
if [ ! -f $PREFIX/include/zstd.h ]; then
|
||||||
if [ -d zstd-$ZSTD_VERSION ]; then
|
if [ -d zstd-$ZSTD_VERSION ]; then
|
||||||
rm -rf zstd-$ZSTD_VERSION
|
rm -rf zstd-$ZSTD_VERSION
|
||||||
@ -910,7 +941,8 @@ if [ ! -f $PREFIX/include/zstd.h ]; then
|
|||||||
popd && popd
|
popd && popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#install jemalloc
|
# TODO(gitbuda): Freeze jmalloc version.
|
||||||
|
log_tool_name "jmalloc"
|
||||||
if [ ! -d $PREFIX/include/jemalloc ]; then
|
if [ ! -d $PREFIX/include/jemalloc ]; then
|
||||||
if [ -d jemalloc ]; then
|
if [ -d jemalloc ]; then
|
||||||
rm -rf jemalloc
|
rm -rf jemalloc
|
||||||
@ -927,7 +959,7 @@ if [ ! -d $PREFIX/include/jemalloc ]; then
|
|||||||
popd
|
popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# install boost
|
log_tool_name "BOOST $BOOST_VERSION"
|
||||||
if [ ! -d $PREFIX/include/boost ]; then
|
if [ ! -d $PREFIX/include/boost ]; then
|
||||||
if [ -d boost_$BOOST_VERSION_UNDERSCORES ]; then
|
if [ -d boost_$BOOST_VERSION_UNDERSCORES ]; then
|
||||||
rm -rf boost_$BOOST_VERSION_UNDERSCORES
|
rm -rf boost_$BOOST_VERSION_UNDERSCORES
|
||||||
@ -935,15 +967,24 @@ if [ ! -d $PREFIX/include/boost ]; then
|
|||||||
tar -xzf ../archives/boost_$BOOST_VERSION_UNDERSCORES.tar.gz
|
tar -xzf ../archives/boost_$BOOST_VERSION_UNDERSCORES.tar.gz
|
||||||
pushd boost_$BOOST_VERSION_UNDERSCORES
|
pushd boost_$BOOST_VERSION_UNDERSCORES
|
||||||
./bootstrap.sh --prefix=$PREFIX --with-toolset=clang --with-python=python3 --without-icu
|
./bootstrap.sh --prefix=$PREFIX --with-toolset=clang --with-python=python3 --without-icu
|
||||||
./b2 toolset=clang -j$CPUS install variant=release link=static cxxstd=20 --disable-icu \
|
if [ "$TOOLCHAIN_STDCXX" = "libstdc++" ]; then
|
||||||
-sZLIB_SOURCE="$PREFIX" -sZLIB_INCLUDE="$PREFIX/include" -sZLIB_LIBPATH="$PREFIX/lib" \
|
./b2 toolset=clang -j$CPUS install variant=release link=static cxxstd=20 --disable-icu \
|
||||||
-sBZIP2_SOURCE="$PREFIX" -sBZIP2_INCLUDE="$PREFIX/include" -sBZIP2_LIBPATH="$PREFIX/lib" \
|
-sZLIB_SOURCE="$PREFIX" -sZLIB_INCLUDE="$PREFIX/include" -sZLIB_LIBPATH="$PREFIX/lib" \
|
||||||
-sLZMA_SOURCE="$PREFIX" -sLZMA_INCLUDE="$PREFIX/include" -sLZMA_LIBPATH="$PREFIX/lib" \
|
-sBZIP2_SOURCE="$PREFIX" -sBZIP2_INCLUDE="$PREFIX/include" -sBZIP2_LIBPATH="$PREFIX/lib" \
|
||||||
-sZSTD_SOURCE="$PREFIX" -sZSTD_INCLUDE="$PREFIX/include" -sZSTD_LIBPATH="$PREFIX/lib"
|
-sLZMA_SOURCE="$PREFIX" -sLZMA_INCLUDE="$PREFIX/include" -sLZMA_LIBPATH="$PREFIX/lib" \
|
||||||
|
-sZSTD_SOURCE="$PREFIX" -sZSTD_INCLUDE="$PREFIX/include" -sZSTD_LIBPATH="$PREFIX/lib"
|
||||||
|
else
|
||||||
|
./b2 toolset=clang -j$CPUS install variant=release link=static cxxstd=20 --disable-icu \
|
||||||
|
cxxflags="-stdlib=libc++" linkflags="-stdlib=libc++" \
|
||||||
|
-sZLIB_SOURCE="$PREFIX" -sZLIB_INCLUDE="$PREFIX/include" -sZLIB_LIBPATH="$PREFIX/lib" \
|
||||||
|
-sBZIP2_SOURCE="$PREFIX" -sBZIP2_INCLUDE="$PREFIX/include" -sBZIP2_LIBPATH="$PREFIX/lib" \
|
||||||
|
-sLZMA_SOURCE="$PREFIX" -sLZMA_INCLUDE="$PREFIX/include" -sLZMA_LIBPATH="$PREFIX/lib" \
|
||||||
|
-sZSTD_SOURCE="$PREFIX" -sZSTD_INCLUDE="$PREFIX/include" -sZSTD_LIBPATH="$PREFIX/lib"
|
||||||
|
fi
|
||||||
popd
|
popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# install double-conversion
|
log_tool_name "double-conversion $DOUBLE_CONVERSION_VERSION"
|
||||||
if [ ! -d $PREFIX/include/double-conversion ]; then
|
if [ ! -d $PREFIX/include/double-conversion ]; then
|
||||||
if [ -d double-conversion-$DOUBLE_CONVERSION_VERSION ]; then
|
if [ -d double-conversion-$DOUBLE_CONVERSION_VERSION ]; then
|
||||||
rm -rf double-conversion-$DOUBLE_CONVERSION_VERSION
|
rm -rf double-conversion-$DOUBLE_CONVERSION_VERSION
|
||||||
@ -958,7 +999,8 @@ if [ ! -d $PREFIX/include/double-conversion ]; then
|
|||||||
popd && popd
|
popd && popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# install gflags
|
# TODO(gitbuda): Freeze gflags version.
|
||||||
|
log_tool_name "gflags"
|
||||||
if [ ! -d $PREFIX/include/gflags ]; then
|
if [ ! -d $PREFIX/include/gflags ]; then
|
||||||
if [ -d gflags ]; then
|
if [ -d gflags ]; then
|
||||||
rm -rf gflags
|
rm -rf gflags
|
||||||
@ -977,7 +1019,7 @@ if [ ! -d $PREFIX/include/gflags ]; then
|
|||||||
popd && popd
|
popd && popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# install libunwind
|
log_tool_name "libunwind $LIBUNWIND_VERSION"
|
||||||
if [ ! -f $PREFIX/include/libunwind.h ]; then
|
if [ ! -f $PREFIX/include/libunwind.h ]; then
|
||||||
if [ -d libunwind-$LIBUNWIND_VERSION ]; then
|
if [ -d libunwind-$LIBUNWIND_VERSION ]; then
|
||||||
rm -rf libunwind-$LIBUNWIND_VERSION
|
rm -rf libunwind-$LIBUNWIND_VERSION
|
||||||
@ -990,7 +1032,7 @@ if [ ! -f $PREFIX/include/libunwind.h ]; then
|
|||||||
popd
|
popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# install glog
|
log_tool_name "glog $GLOG_VERSION"
|
||||||
if [ ! -d $PREFIX/include/glog ]; then
|
if [ ! -d $PREFIX/include/glog ]; then
|
||||||
if [ -d glog-$GLOG_VERSION ]; then
|
if [ -d glog-$GLOG_VERSION ]; then
|
||||||
rm -rf glog-$GLOG_VERSION
|
rm -rf glog-$GLOG_VERSION
|
||||||
@ -1004,7 +1046,7 @@ if [ ! -d $PREFIX/include/glog ]; then
|
|||||||
popd && popd
|
popd && popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# install libevent
|
log_tool_name "libevent $LIBEVENT_VERSION"
|
||||||
if [ ! -d $PREFIX/include/event2 ]; then
|
if [ ! -d $PREFIX/include/event2 ]; then
|
||||||
if [ -d libevent-$LIBEVENT_VERSION ]; then
|
if [ -d libevent-$LIBEVENT_VERSION ]; then
|
||||||
rm -rf libevent-$LIBEVENT_VERSION
|
rm -rf libevent-$LIBEVENT_VERSION
|
||||||
@ -1023,7 +1065,7 @@ if [ ! -d $PREFIX/include/event2 ]; then
|
|||||||
popd && popd
|
popd && popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# install snappy
|
log_tool_name "snappy $SNAPPY_VERSION"
|
||||||
if [ ! -f $PREFIX/include/snappy.h ]; then
|
if [ ! -f $PREFIX/include/snappy.h ]; then
|
||||||
if [ -d snappy-$SNAPPY_VERSION ]; then
|
if [ -d snappy-$SNAPPY_VERSION ]; then
|
||||||
rm -rf snappy-$SNAPPY_VERSION
|
rm -rf snappy-$SNAPPY_VERSION
|
||||||
@ -1041,7 +1083,7 @@ if [ ! -f $PREFIX/include/snappy.h ]; then
|
|||||||
popd && popd
|
popd && popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# install libsodium
|
log_tool_name "libsodium $LIBSODIUM_VERSION"
|
||||||
if [ ! -f $PREFIX/include/sodium.h ]; then
|
if [ ! -f $PREFIX/include/sodium.h ]; then
|
||||||
if [ -d libsodium-$LIBSODIUM_VERSION ]; then
|
if [ -d libsodium-$LIBSODIUM_VERSION ]; then
|
||||||
rm -rf libsodium-$LIBSODIUM_VERSION
|
rm -rf libsodium-$LIBSODIUM_VERSION
|
||||||
@ -1053,7 +1095,7 @@ if [ ! -f $PREFIX/include/sodium.h ]; then
|
|||||||
popd
|
popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# install libaio
|
log_tool_name "libaio $LIBAIO_VERSION"
|
||||||
if [ ! -f $PREFIX/include/libaio.h ]; then
|
if [ ! -f $PREFIX/include/libaio.h ]; then
|
||||||
if [ -d libaio-$LIBAIO_VERSION ]; then
|
if [ -d libaio-$LIBAIO_VERSION ]; then
|
||||||
rm -rf libaio-$LIBAIO_VERSION
|
rm -rf libaio-$LIBAIO_VERSION
|
||||||
@ -1064,7 +1106,7 @@ if [ ! -f $PREFIX/include/libaio.h ]; then
|
|||||||
popd
|
popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# install folly
|
log_tool_name "folly $FBLIBS_VERSION"
|
||||||
if [ ! -d $PREFIX/include/folly ]; then
|
if [ ! -d $PREFIX/include/folly ]; then
|
||||||
if [ -d folly-$FBLIBS_VERSION ]; then
|
if [ -d folly-$FBLIBS_VERSION ]; then
|
||||||
rm -rf folly-$FBLIBS_VERSION
|
rm -rf folly-$FBLIBS_VERSION
|
||||||
@ -1085,7 +1127,7 @@ if [ ! -d $PREFIX/include/folly ]; then
|
|||||||
popd && popd
|
popd && popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# install fizz
|
log_tool_name "fizz $FBLIBS_VERSION"
|
||||||
if [ ! -d $PREFIX/include/fizz ]; then
|
if [ ! -d $PREFIX/include/fizz ]; then
|
||||||
if [ -d fizz-$FBLIBS_VERSION ]; then
|
if [ -d fizz-$FBLIBS_VERSION ]; then
|
||||||
rm -rf fizz-$FBLIBS_VERSION
|
rm -rf fizz-$FBLIBS_VERSION
|
||||||
@ -1104,7 +1146,7 @@ if [ ! -d $PREFIX/include/fizz ]; then
|
|||||||
popd && popd
|
popd && popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# install wangle
|
log_tool_name "wangle FBLIBS_VERSION"
|
||||||
if [ ! -d $PREFIX/include/wangle ]; then
|
if [ ! -d $PREFIX/include/wangle ]; then
|
||||||
if [ -d wangle-$FBLIBS_VERSION ]; then
|
if [ -d wangle-$FBLIBS_VERSION ]; then
|
||||||
rm -rf wangle-$FBLIBS_VERSION
|
rm -rf wangle-$FBLIBS_VERSION
|
||||||
@ -1123,7 +1165,7 @@ if [ ! -d $PREFIX/include/wangle ]; then
|
|||||||
popd && popd
|
popd && popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# install proxygen
|
log_tool_name "proxygen $FBLIBS_VERSION"
|
||||||
if [ ! -d $PREFIX/include/proxygen ]; then
|
if [ ! -d $PREFIX/include/proxygen ]; then
|
||||||
if [ -d proxygen-$FBLIBS_VERSION ]; then
|
if [ -d proxygen-$FBLIBS_VERSION ]; then
|
||||||
rm -rf proxygen-$FBLIBS_VERSION
|
rm -rf proxygen-$FBLIBS_VERSION
|
||||||
@ -1144,7 +1186,7 @@ if [ ! -d $PREFIX/include/proxygen ]; then
|
|||||||
popd && popd
|
popd && popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# install flex
|
log_tool_name "flex $FBLIBS_VERSION"
|
||||||
if [ ! -f $PREFIX/include/FlexLexer.h ]; then
|
if [ ! -f $PREFIX/include/FlexLexer.h ]; then
|
||||||
if [ -d flex-$FLEX_VERSION ]; then
|
if [ -d flex-$FLEX_VERSION ]; then
|
||||||
rm -rf flex-$FLEX_VERSION
|
rm -rf flex-$FLEX_VERSION
|
||||||
@ -1156,7 +1198,7 @@ if [ ! -f $PREFIX/include/FlexLexer.h ]; then
|
|||||||
popd
|
popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# install fbthrift
|
log_tool_name "fbthrift $FBLIBS_VERSION"
|
||||||
if [ ! -d $PREFIX/include/thrift ]; then
|
if [ ! -d $PREFIX/include/thrift ]; then
|
||||||
if [ -d fbthrift-$FBLIBS_VERSION ]; then
|
if [ -d fbthrift-$FBLIBS_VERSION ]; then
|
||||||
rm -rf fbthrift-$FBLIBS_VERSION
|
rm -rf fbthrift-$FBLIBS_VERSION
|
||||||
@ -1166,10 +1208,15 @@ if [ ! -d $PREFIX/include/thrift ]; then
|
|||||||
# build is used by facebook builder
|
# build is used by facebook builder
|
||||||
mkdir _build
|
mkdir _build
|
||||||
pushd _build
|
pushd _build
|
||||||
|
if [ "$TOOLCHAIN_STDCXX" = "libstdc++" ]; then
|
||||||
|
CMAKE_CXX_FLAGS="-fsized-deallocation"
|
||||||
|
else
|
||||||
|
CMAKE_CXX_FLAGS="-fsized-deallocation -stdlib=libc++"
|
||||||
|
fi
|
||||||
cmake .. $COMMON_CMAKE_FLAGS \
|
cmake .. $COMMON_CMAKE_FLAGS \
|
||||||
-Denable_tests=OFF \
|
-Denable_tests=OFF \
|
||||||
-DGFLAGS_NOTHREADS=OFF \
|
-DGFLAGS_NOTHREADS=OFF \
|
||||||
-DCMAKE_CXX_FLAGS=-fsized-deallocation
|
-DCMAKE_CXX_FLAGS="$CMAKE_CXX_FLAGS"
|
||||||
make -j$CPUS install
|
make -j$CPUS install
|
||||||
popd
|
popd
|
||||||
fi
|
fi
|
||||||
@ -1192,7 +1239,12 @@ if [ ! -f $NAME-binaries-$DISTRO.tar.gz ]; then
|
|||||||
DISTRO_FULL_NAME="$DISTRO_FULL_NAME-amd64"
|
DISTRO_FULL_NAME="$DISTRO_FULL_NAME-amd64"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
if [ "$TOOLCHAIN_STDCXX" = "libstdc++" ]; then
|
||||||
|
# Pass because infra scripts assume there is not C++ standard lib in the name.
|
||||||
|
echo "NOTE: Not adding anything to the archive name that GCC C++ standard lib is used."
|
||||||
|
else
|
||||||
|
DISTRO_FULL_NAME="$DISTRO_FULL_NAME-libc++"
|
||||||
|
fi
|
||||||
tar --owner=root --group=root -cpvzf $NAME-binaries-$DISTRO_FULL_NAME.tar.gz -C /opt $NAME
|
tar --owner=root --group=root -cpvzf $NAME-binaries-$DISTRO_FULL_NAME.tar.gz -C /opt $NAME
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ ADDITIONAL USE GRANT: You may use the Licensed Work in accordance with the
|
|||||||
3. using the Licensed Work to create a work or solution
|
3. using the Licensed Work to create a work or solution
|
||||||
which competes (or might reasonably be expected to
|
which competes (or might reasonably be expected to
|
||||||
compete) with the Licensed Work.
|
compete) with the Licensed Work.
|
||||||
CHANGE DATE: 2026-07-10
|
CHANGE DATE: 2026-07-11
|
||||||
CHANGE LICENSE: Apache License, Version 2.0
|
CHANGE LICENSE: Apache License, Version 2.0
|
||||||
|
|
||||||
For information about alternative licensing arrangements, please visit: https://memgraph.com/legal.
|
For information about alternative licensing arrangements, please visit: https://memgraph.com/legal.
|
||||||
|
@ -2,8 +2,8 @@ MEMGRAPH
|
|||||||
ENTERPRISE LICENCE AGREEMENT
|
ENTERPRISE LICENCE AGREEMENT
|
||||||
|
|
||||||
|
|
||||||
Memgraph Limited is registered in England under registration 10195084 and has its registered office at Suite 4,
|
Memgraph Limited is registered in England under registration 10195084 and has its registered office at 90a High Street,
|
||||||
Ironstone House, Ironstone Way, Brixworth, Northampton, NN6 9UD (“Memgraph”).
|
Hertfordshire, Berkhamsted, HP4 2BL United Kingdom ("Memgraph").
|
||||||
|
|
||||||
|
|
||||||
Memgraph agrees to license and/or grant you (the “Customer”) access to the Software ( as defined below) and provide
|
Memgraph agrees to license and/or grant you (the “Customer”) access to the Software ( as defined below) and provide
|
||||||
|
@ -1,4 +1,11 @@
|
|||||||
# mgp
|
# mgp
|
||||||
|
|
||||||
PyPi package used for type hinting when creating MAGE modules. The get started
|
PyPi package used for type hinting when creating query modules. Repository of already available query modules is called [MAGE](https://github.com/memgraph/mage).
|
||||||
using MAGE repository checkout the repository here: https://github.com/memgraph/mage.
|
|
||||||
|
## 🎬 Get started
|
||||||
|
|
||||||
|
To learn more, head over to the [docs for the query modules Python API](https://memgraph.com/docs/memgraph/reference-guide/query-modules/api/python-api). To get started with query modules, check out the [how-to guide](https://memgraph.com/docs/memgraph/how-to-guides/query-modules) on Memgraph docs.
|
||||||
|
|
||||||
|
## 🔢 Versioning
|
||||||
|
|
||||||
|
- mgp v1.1 is compatible with Memgraph >= 2.4.0
|
||||||
|
@ -257,3 +257,11 @@ class _MODULE:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def add_function(wrapper):
|
def add_function(wrapper):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class SOURCE_TYPE_KAFKA:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class SOURCE_TYPE_PULSAR:
|
||||||
|
pass
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "mgp"
|
name = "mgp"
|
||||||
version = "1.0.0"
|
version = "1.1.0"
|
||||||
description = "Memgraph's module for developing MAGE modules. Used only for type hinting!"
|
description = "Memgraph's module for developing MAGE modules. Used only for type hinting!"
|
||||||
authors = [
|
authors = [
|
||||||
"MasterMedo <mislav.vuletic@gmail.com>",
|
|
||||||
"jbajic <jure.bajic@memgraph.io>",
|
|
||||||
"katarinasupe <katarina.supe@memgraph.io>",
|
"katarinasupe <katarina.supe@memgraph.io>",
|
||||||
|
"jbajic <jure.bajic@memgraph.io>",
|
||||||
"antejavor <ante.javor@memgraph.io>",
|
"antejavor <ante.javor@memgraph.io>",
|
||||||
"antaljanosbenjamin <benjamin.antal@memgraph.io>",
|
"antaljanosbenjamin <benjamin.antal@memgraph.io>",
|
||||||
|
"MasterMedo <mislav.vuletic@gmail.com>",
|
||||||
]
|
]
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
@ -15,10 +15,11 @@ add_subdirectory(query)
|
|||||||
add_subdirectory(glue)
|
add_subdirectory(glue)
|
||||||
add_subdirectory(slk)
|
add_subdirectory(slk)
|
||||||
add_subdirectory(rpc)
|
add_subdirectory(rpc)
|
||||||
|
add_subdirectory(license)
|
||||||
add_subdirectory(auth)
|
add_subdirectory(auth)
|
||||||
|
|
||||||
if (MG_ENTERPRISE)
|
if(MG_ENTERPRISE)
|
||||||
add_subdirectory(audit)
|
add_subdirectory(audit)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
string(TOLOWER ${CMAKE_BUILD_TYPE} lower_build_type)
|
string(TOLOWER ${CMAKE_BUILD_TYPE} lower_build_type)
|
||||||
@ -36,68 +37,76 @@ set(mg_single_node_v2_sources
|
|||||||
)
|
)
|
||||||
|
|
||||||
set(mg_single_node_v2_libs stdc++fs Threads::Threads
|
set(mg_single_node_v2_libs stdc++fs Threads::Threads
|
||||||
telemetry_lib mg-query mg-communication mg-memory mg-utils mg-auth mg-license mg-settings mg-glue)
|
mg-telemetry mg-query mg-communication mg-memory mg-utils mg-auth mg-license mg-settings mg-glue)
|
||||||
if (MG_ENTERPRISE)
|
|
||||||
# These are enterprise subsystems
|
if(MG_ENTERPRISE)
|
||||||
set(mg_single_node_v2_libs ${mg_single_node_v2_libs} mg-audit)
|
# These are enterprise subsystems
|
||||||
|
set(mg_single_node_v2_libs ${mg_single_node_v2_libs} mg-audit)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# memgraph main executable
|
# memgraph main executable
|
||||||
add_executable(memgraph ${mg_single_node_v2_sources})
|
add_executable(memgraph ${mg_single_node_v2_sources})
|
||||||
target_include_directories(memgraph PUBLIC ${CMAKE_SOURCE_DIR}/include)
|
target_include_directories(memgraph PUBLIC ${CMAKE_SOURCE_DIR}/include)
|
||||||
target_link_libraries(memgraph ${mg_single_node_v2_libs})
|
target_link_libraries(memgraph ${mg_single_node_v2_libs})
|
||||||
|
|
||||||
# NOTE: `include/mg_procedure.syms` describes a pattern match for symbols which
|
# NOTE: `include/mg_procedure.syms` describes a pattern match for symbols which
|
||||||
# should be dynamically exported, so that `dlopen` can correctly link the
|
# should be dynamically exported, so that `dlopen` can correctly link the
|
||||||
# symbols in custom procedure module libraries.
|
# symbols in custom procedure module libraries.
|
||||||
target_link_libraries(memgraph "-Wl,--dynamic-list=${CMAKE_SOURCE_DIR}/include/mg_procedure.syms")
|
target_link_libraries(memgraph "-Wl,--dynamic-list=${CMAKE_SOURCE_DIR}/include/mg_procedure.syms")
|
||||||
set_target_properties(memgraph PROPERTIES
|
set_target_properties(memgraph PROPERTIES
|
||||||
# Set the executable output name to include version information.
|
|
||||||
OUTPUT_NAME "memgraph-${MEMGRAPH_VERSION}_${CMAKE_BUILD_TYPE}"
|
# Set the executable output name to include version information.
|
||||||
# Output the executable in main binary dir.
|
OUTPUT_NAME "memgraph-${MEMGRAPH_VERSION}_${CMAKE_BUILD_TYPE}"
|
||||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
|
||||||
|
# Output the executable in main binary dir.
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||||
|
|
||||||
# Create symlink to the built executable.
|
# Create symlink to the built executable.
|
||||||
add_custom_command(TARGET memgraph POST_BUILD
|
add_custom_command(TARGET memgraph POST_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E create_symlink $<TARGET_FILE:memgraph> ${CMAKE_BINARY_DIR}/memgraph
|
COMMAND ${CMAKE_COMMAND} -E create_symlink $<TARGET_FILE:memgraph> ${CMAKE_BINARY_DIR}/memgraph
|
||||||
BYPRODUCTS ${CMAKE_BINARY_DIR}/memgraph
|
BYPRODUCTS ${CMAKE_BINARY_DIR}/memgraph
|
||||||
COMMENT "Creating symlink to memgraph executable")
|
COMMENT "Creating symlink to memgraph executable")
|
||||||
|
|
||||||
# Emulate the installed python_support, by creating a symlink
|
# Emulate the installed python_support, by creating a symlink
|
||||||
add_custom_command(TARGET memgraph POST_BUILD
|
add_custom_command(TARGET memgraph POST_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_SOURCE_DIR}/include ${CMAKE_BINARY_DIR}/python_support
|
COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_SOURCE_DIR}/include ${CMAKE_BINARY_DIR}/python_support
|
||||||
BYPRODUCTS ${CMAKE_BINARY_DIR}/python_support
|
BYPRODUCTS ${CMAKE_BINARY_DIR}/python_support
|
||||||
COMMENT "Creating symlink for python_support")
|
COMMENT "Creating symlink for python_support")
|
||||||
|
|
||||||
# Strip the executable in release build.
|
# Strip the executable in release build.
|
||||||
if (lower_build_type STREQUAL "release")
|
if(lower_build_type STREQUAL "release")
|
||||||
add_custom_command(TARGET memgraph POST_BUILD
|
add_custom_command(TARGET memgraph POST_BUILD
|
||||||
COMMAND strip -s $<TARGET_FILE:memgraph>
|
COMMAND strip -s $<TARGET_FILE:memgraph>
|
||||||
COMMENT "Stripping symbols and sections from memgraph")
|
COMMENT "Stripping symbols and sections from memgraph")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Generate the configuration file.
|
# Generate the configuration file.
|
||||||
add_custom_command(TARGET memgraph POST_BUILD
|
add_custom_command(TARGET memgraph POST_BUILD
|
||||||
COMMAND ${CMAKE_SOURCE_DIR}/config/generate.py
|
COMMAND ${CMAKE_SOURCE_DIR}/config/generate.py
|
||||||
${CMAKE_BINARY_DIR}/memgraph
|
${CMAKE_BINARY_DIR}/memgraph
|
||||||
${CMAKE_BINARY_DIR}/config/memgraph.conf
|
${CMAKE_BINARY_DIR}/config/memgraph.conf
|
||||||
DEPENDS ${CMAKE_SOURCE_DIR}/config/generate.py
|
DEPENDS ${CMAKE_SOURCE_DIR}/config/generate.py
|
||||||
${CMAKE_SOURCE_DIR}/config/flags.yaml
|
${CMAKE_SOURCE_DIR}/config/flags.yaml
|
||||||
BYPRODUCTS ${CMAKE_BINARY_DIR}/config/memgraph.conf
|
BYPRODUCTS ${CMAKE_BINARY_DIR}/config/memgraph.conf
|
||||||
COMMENT "Generating memgraph configuration file")
|
COMMENT "Generating memgraph configuration file")
|
||||||
|
|
||||||
# Everything here is under "memgraph" install component.
|
# Everything here is under "memgraph" install component.
|
||||||
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "memgraph")
|
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "memgraph")
|
||||||
|
|
||||||
# TODO: Default directory permissions to 755
|
# TODO: Default directory permissions to 755
|
||||||
# NOTE: This is added in CMake 3.11, so enable it then
|
# NOTE: This is added in CMake 3.11, so enable it then
|
||||||
#set(CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS
|
# set(CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS
|
||||||
# OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ WORLD_READ)
|
# OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ WORLD_READ)
|
||||||
|
|
||||||
# Install and rename executable to just 'memgraph' Since we have to rename,
|
# Install and rename executable to just 'memgraph' Since we have to rename,
|
||||||
# we cannot use the recommended `install(TARGETS ...)`.
|
# we cannot use the recommended `install(TARGETS ...)`.
|
||||||
install(PROGRAMS $<TARGET_FILE:memgraph>
|
install(PROGRAMS $<TARGET_FILE:memgraph>
|
||||||
DESTINATION lib/memgraph RENAME memgraph)
|
DESTINATION lib/memgraph RENAME memgraph)
|
||||||
|
|
||||||
# Install Python source for supporting our embedded Python.
|
# Install Python source for supporting our embedded Python.
|
||||||
install(FILES ${CMAKE_SOURCE_DIR}/include/mgp.py
|
install(FILES ${CMAKE_SOURCE_DIR}/include/mgp.py
|
||||||
DESTINATION lib/memgraph/python_support)
|
DESTINATION lib/memgraph/python_support)
|
||||||
|
|
||||||
# Install the includes file for writing custom procedures in C and C++>
|
# Install the includes file for writing custom procedures in C and C++>
|
||||||
install(FILES ${CMAKE_SOURCE_DIR}/include/mg_procedure.h
|
install(FILES ${CMAKE_SOURCE_DIR}/include/mg_procedure.h
|
||||||
DESTINATION include/memgraph)
|
DESTINATION include/memgraph)
|
||||||
@ -107,9 +116,11 @@ install(FILES ${CMAKE_SOURCE_DIR}/include/mg_exceptions.hpp
|
|||||||
DESTINATION include/memgraph)
|
DESTINATION include/memgraph)
|
||||||
install(FILES ${CMAKE_SOURCE_DIR}/include/mgp.hpp
|
install(FILES ${CMAKE_SOURCE_DIR}/include/mgp.hpp
|
||||||
DESTINATION include/memgraph)
|
DESTINATION include/memgraph)
|
||||||
|
|
||||||
# Install the config file (must use absolute path).
|
# Install the config file (must use absolute path).
|
||||||
install(FILES ${CMAKE_BINARY_DIR}/config/memgraph.conf
|
install(FILES ${CMAKE_BINARY_DIR}/config/memgraph.conf
|
||||||
DESTINATION /etc/memgraph RENAME memgraph.conf)
|
DESTINATION /etc/memgraph RENAME memgraph.conf)
|
||||||
|
|
||||||
# Install logrotate configuration (must use absolute path).
|
# Install logrotate configuration (must use absolute path).
|
||||||
install(FILES ${CMAKE_SOURCE_DIR}/release/logrotate.conf
|
install(FILES ${CMAKE_SOURCE_DIR}/release/logrotate.conf
|
||||||
DESTINATION /etc/logrotate.d RENAME memgraph)
|
DESTINATION /etc/logrotate.d RENAME memgraph)
|
||||||
@ -125,15 +136,14 @@ install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}/var/log/memgraph
|
|||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
# Memgraph CSV Import Tool Executable
|
# Memgraph CSV Import Tool Executable
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
add_executable(mg_import_csv mg_import_csv.cpp)
|
add_executable(mg_import_csv mg_import_csv.cpp)
|
||||||
target_link_libraries(mg_import_csv mg-storage-v2)
|
target_link_libraries(mg_import_csv mg-storage-v2)
|
||||||
|
|
||||||
# Strip the executable in release build.
|
# Strip the executable in release build.
|
||||||
if (lower_build_type STREQUAL "release")
|
if(lower_build_type STREQUAL "release")
|
||||||
add_custom_command(TARGET mg_import_csv POST_BUILD
|
add_custom_command(TARGET mg_import_csv POST_BUILD
|
||||||
COMMAND strip -s mg_import_csv
|
COMMAND strip -s mg_import_csv
|
||||||
COMMENT "Stripping symbols and sections from mg_import_csv")
|
COMMENT "Stripping symbols and sections from mg_import_csv")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
install(TARGETS mg_import_csv RUNTIME DESTINATION bin)
|
install(TARGETS mg_import_csv RUNTIME DESTINATION bin)
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
|
||||||
#include "auth/exceptions.hpp"
|
#include "auth/exceptions.hpp"
|
||||||
|
#include "license/license.hpp"
|
||||||
#include "utils/flag_validation.hpp"
|
#include "utils/flag_validation.hpp"
|
||||||
#include "utils/license.hpp"
|
|
||||||
#include "utils/logging.hpp"
|
#include "utils/logging.hpp"
|
||||||
#include "utils/message.hpp"
|
#include "utils/message.hpp"
|
||||||
#include "utils/settings.hpp"
|
#include "utils/settings.hpp"
|
||||||
@ -68,10 +68,9 @@ Auth::Auth(const std::string &storage_directory) : storage_(storage_directory),
|
|||||||
|
|
||||||
std::optional<User> Auth::Authenticate(const std::string &username, const std::string &password) {
|
std::optional<User> Auth::Authenticate(const std::string &username, const std::string &password) {
|
||||||
if (module_.IsUsed()) {
|
if (module_.IsUsed()) {
|
||||||
const auto license_check_result = utils::license::global_license_checker.IsValidLicense(utils::global_settings);
|
const auto license_check_result = license::global_license_checker.IsEnterpriseValid(utils::global_settings);
|
||||||
if (license_check_result.HasError()) {
|
if (license_check_result.HasError()) {
|
||||||
spdlog::warn(
|
spdlog::warn(license::LicenseCheckErrorToString(license_check_result.GetError(), "authentication modules"));
|
||||||
utils::license::LicenseCheckErrorToString(license_check_result.GetError(), "authentication modules"));
|
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
|
|
||||||
#include "auth/crypto.hpp"
|
#include "auth/crypto.hpp"
|
||||||
#include "auth/exceptions.hpp"
|
#include "auth/exceptions.hpp"
|
||||||
|
#include "license/license.hpp"
|
||||||
#include "utils/cast.hpp"
|
#include "utils/cast.hpp"
|
||||||
#include "utils/license.hpp"
|
|
||||||
#include "utils/logging.hpp"
|
#include "utils/logging.hpp"
|
||||||
#include "utils/settings.hpp"
|
#include "utils/settings.hpp"
|
||||||
#include "utils/string.hpp"
|
#include "utils/string.hpp"
|
||||||
@ -242,7 +242,7 @@ FineGrainedAccessPermissions::FineGrainedAccessPermissions(const std::unordered_
|
|||||||
|
|
||||||
PermissionLevel FineGrainedAccessPermissions::Has(const std::string &permission,
|
PermissionLevel FineGrainedAccessPermissions::Has(const std::string &permission,
|
||||||
const FineGrainedPermission fine_grained_permission) const {
|
const FineGrainedPermission fine_grained_permission) const {
|
||||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
return PermissionLevel::GRANT;
|
return PermissionLevel::GRANT;
|
||||||
}
|
}
|
||||||
const auto concrete_permission = std::invoke([&]() -> uint64_t {
|
const auto concrete_permission = std::invoke([&]() -> uint64_t {
|
||||||
@ -281,7 +281,7 @@ void FineGrainedAccessPermissions::Revoke(const std::string &permission) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
nlohmann::json FineGrainedAccessPermissions::Serialize() const {
|
nlohmann::json FineGrainedAccessPermissions::Serialize() const {
|
||||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
nlohmann::json data = nlohmann::json::object();
|
nlohmann::json data = nlohmann::json::object();
|
||||||
@ -294,7 +294,7 @@ FineGrainedAccessPermissions FineGrainedAccessPermissions::Deserialize(const nlo
|
|||||||
if (!data.is_object()) {
|
if (!data.is_object()) {
|
||||||
throw AuthException("Couldn't load permissions data!");
|
throw AuthException("Couldn't load permissions data!");
|
||||||
}
|
}
|
||||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
return FineGrainedAccessPermissions{};
|
return FineGrainedAccessPermissions{};
|
||||||
}
|
}
|
||||||
std::optional<uint64_t> global_permission;
|
std::optional<uint64_t> global_permission;
|
||||||
@ -347,7 +347,7 @@ const FineGrainedAccessPermissions &FineGrainedAccessHandler::edge_type_permissi
|
|||||||
FineGrainedAccessPermissions &FineGrainedAccessHandler::edge_type_permissions() { return edge_type_permissions_; }
|
FineGrainedAccessPermissions &FineGrainedAccessHandler::edge_type_permissions() { return edge_type_permissions_; }
|
||||||
|
|
||||||
nlohmann::json FineGrainedAccessHandler::Serialize() const {
|
nlohmann::json FineGrainedAccessHandler::Serialize() const {
|
||||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
nlohmann::json data = nlohmann::json::object();
|
nlohmann::json data = nlohmann::json::object();
|
||||||
@ -363,7 +363,7 @@ FineGrainedAccessHandler FineGrainedAccessHandler::Deserialize(const nlohmann::j
|
|||||||
if (!data["label_permissions"].is_object() || !data["edge_type_permissions"].is_object()) {
|
if (!data["label_permissions"].is_object() || !data["edge_type_permissions"].is_object()) {
|
||||||
throw AuthException("Couldn't load label_permissions or edge_type_permissions data!");
|
throw AuthException("Couldn't load label_permissions or edge_type_permissions data!");
|
||||||
}
|
}
|
||||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
return FineGrainedAccessHandler{};
|
return FineGrainedAccessHandler{};
|
||||||
}
|
}
|
||||||
auto label_permissions = FineGrainedAccessPermissions::Deserialize(data["label_permissions"]);
|
auto label_permissions = FineGrainedAccessPermissions::Deserialize(data["label_permissions"]);
|
||||||
@ -414,7 +414,7 @@ nlohmann::json Role::Serialize() const {
|
|||||||
data["rolename"] = rolename_;
|
data["rolename"] = rolename_;
|
||||||
data["permissions"] = permissions_.Serialize();
|
data["permissions"] = permissions_.Serialize();
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
data["fine_grained_access_handler"] = fine_grained_access_handler_.Serialize();
|
data["fine_grained_access_handler"] = fine_grained_access_handler_.Serialize();
|
||||||
} else {
|
} else {
|
||||||
data["fine_grained_access_handler"] = {};
|
data["fine_grained_access_handler"] = {};
|
||||||
@ -432,7 +432,7 @@ Role Role::Deserialize(const nlohmann::json &data) {
|
|||||||
}
|
}
|
||||||
auto permissions = Permissions::Deserialize(data["permissions"]);
|
auto permissions = Permissions::Deserialize(data["permissions"]);
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
if (!data["fine_grained_access_handler"].is_object()) {
|
if (!data["fine_grained_access_handler"].is_object()) {
|
||||||
throw AuthException("Couldn't load user data!");
|
throw AuthException("Couldn't load user data!");
|
||||||
}
|
}
|
||||||
@ -445,7 +445,7 @@ Role Role::Deserialize(const nlohmann::json &data) {
|
|||||||
|
|
||||||
bool operator==(const Role &first, const Role &second) {
|
bool operator==(const Role &first, const Role &second) {
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
return first.rolename_ == second.rolename_ && first.permissions_ == second.permissions_ &&
|
return first.rolename_ == second.rolename_ && first.permissions_ == second.permissions_ &&
|
||||||
first.fine_grained_access_handler_ == second.fine_grained_access_handler_;
|
first.fine_grained_access_handler_ == second.fine_grained_access_handler_;
|
||||||
}
|
}
|
||||||
@ -483,13 +483,13 @@ void User::UpdatePassword(const std::optional<std::string> &password) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (FLAGS_auth_password_strength_regex != default_password_regex) {
|
if (FLAGS_auth_password_strength_regex != default_password_regex) {
|
||||||
if (const auto license_check_result = utils::license::global_license_checker.IsValidLicense(utils::global_settings);
|
if (const auto license_check_result = license::global_license_checker.IsEnterpriseValid(utils::global_settings);
|
||||||
license_check_result.HasError()) {
|
license_check_result.HasError()) {
|
||||||
throw AuthException(
|
throw AuthException(
|
||||||
"Custom password regex is a Memgraph Enterprise feature. Please set the config "
|
"Custom password regex is a Memgraph Enterprise feature. Please set the config "
|
||||||
"(\"--auth-password-strength-regex\") to its default value (\"{}\") or remove the flag.\n{}",
|
"(\"--auth-password-strength-regex\") to its default value (\"{}\") or remove the flag.\n{}",
|
||||||
default_password_regex,
|
default_password_regex,
|
||||||
utils::license::LicenseCheckErrorToString(license_check_result.GetError(), "password regex"));
|
license::LicenseCheckErrorToString(license_check_result.GetError(), "password regex"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::regex re(FLAGS_auth_password_strength_regex);
|
std::regex re(FLAGS_auth_password_strength_regex);
|
||||||
@ -517,7 +517,7 @@ Permissions User::GetPermissions() const {
|
|||||||
|
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
FineGrainedAccessPermissions User::GetFineGrainedAccessLabelPermissions() const {
|
FineGrainedAccessPermissions User::GetFineGrainedAccessLabelPermissions() const {
|
||||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
return FineGrainedAccessPermissions{};
|
return FineGrainedAccessPermissions{};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -530,7 +530,7 @@ FineGrainedAccessPermissions User::GetFineGrainedAccessLabelPermissions() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
FineGrainedAccessPermissions User::GetFineGrainedAccessEdgeTypePermissions() const {
|
FineGrainedAccessPermissions User::GetFineGrainedAccessEdgeTypePermissions() const {
|
||||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
return FineGrainedAccessPermissions{};
|
return FineGrainedAccessPermissions{};
|
||||||
}
|
}
|
||||||
if (role_) {
|
if (role_) {
|
||||||
@ -563,7 +563,7 @@ nlohmann::json User::Serialize() const {
|
|||||||
data["password_hash"] = password_hash_;
|
data["password_hash"] = password_hash_;
|
||||||
data["permissions"] = permissions_.Serialize();
|
data["permissions"] = permissions_.Serialize();
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
data["fine_grained_access_handler"] = fine_grained_access_handler_.Serialize();
|
data["fine_grained_access_handler"] = fine_grained_access_handler_.Serialize();
|
||||||
} else {
|
} else {
|
||||||
data["fine_grained_access_handler"] = {};
|
data["fine_grained_access_handler"] = {};
|
||||||
@ -582,7 +582,7 @@ User User::Deserialize(const nlohmann::json &data) {
|
|||||||
}
|
}
|
||||||
auto permissions = Permissions::Deserialize(data["permissions"]);
|
auto permissions = Permissions::Deserialize(data["permissions"]);
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
if (!data["fine_grained_access_handler"].is_object()) {
|
if (!data["fine_grained_access_handler"].is_object()) {
|
||||||
throw AuthException("Couldn't load user data!");
|
throw AuthException("Couldn't load user data!");
|
||||||
}
|
}
|
||||||
@ -595,7 +595,7 @@ User User::Deserialize(const nlohmann::json &data) {
|
|||||||
|
|
||||||
bool operator==(const User &first, const User &second) {
|
bool operator==(const User &first, const User &second) {
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
return first.username_ == second.username_ && first.password_hash_ == second.password_hash_ &&
|
return first.username_ == second.username_ && first.password_hash_ == second.password_hash_ &&
|
||||||
first.permissions_ == second.permissions_ && first.role_ == second.role_ &&
|
first.permissions_ == second.permissions_ && first.role_ == second.role_ &&
|
||||||
first.fine_grained_access_handler_ == second.fine_grained_access_handler_;
|
first.fine_grained_access_handler_ == second.fine_grained_access_handler_;
|
||||||
|
@ -14,8 +14,8 @@
|
|||||||
#include "auth/auth.hpp"
|
#include "auth/auth.hpp"
|
||||||
#include "auth/models.hpp"
|
#include "auth/models.hpp"
|
||||||
#include "glue/auth.hpp"
|
#include "glue/auth.hpp"
|
||||||
|
#include "license/license.hpp"
|
||||||
#include "query/frontend/ast/ast.hpp"
|
#include "query/frontend/ast/ast.hpp"
|
||||||
#include "utils/license.hpp"
|
|
||||||
#include "utils/synchronized.hpp"
|
#include "utils/synchronized.hpp"
|
||||||
|
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
@ -23,7 +23,7 @@ namespace {
|
|||||||
bool IsUserAuthorizedLabels(const memgraph::auth::User &user, const memgraph::query::DbAccessor *dba,
|
bool IsUserAuthorizedLabels(const memgraph::auth::User &user, const memgraph::query::DbAccessor *dba,
|
||||||
const std::vector<memgraph::storage::LabelId> &labels,
|
const std::vector<memgraph::storage::LabelId> &labels,
|
||||||
const memgraph::query::AuthQuery::FineGrainedPrivilege fine_grained_privilege) {
|
const memgraph::query::AuthQuery::FineGrainedPrivilege fine_grained_privilege) {
|
||||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return std::all_of(labels.begin(), labels.end(), [dba, &user, fine_grained_privilege](const auto &label) {
|
return std::all_of(labels.begin(), labels.end(), [dba, &user, fine_grained_privilege](const auto &label) {
|
||||||
@ -35,7 +35,7 @@ bool IsUserAuthorizedLabels(const memgraph::auth::User &user, const memgraph::qu
|
|||||||
|
|
||||||
bool IsUserAuthorizedGloballyLabels(const memgraph::auth::User &user,
|
bool IsUserAuthorizedGloballyLabels(const memgraph::auth::User &user,
|
||||||
const memgraph::auth::FineGrainedPermission fine_grained_permission) {
|
const memgraph::auth::FineGrainedPermission fine_grained_permission) {
|
||||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return user.GetFineGrainedAccessLabelPermissions().Has(memgraph::auth::kAsterisk, fine_grained_permission) ==
|
return user.GetFineGrainedAccessLabelPermissions().Has(memgraph::auth::kAsterisk, fine_grained_permission) ==
|
||||||
@ -44,7 +44,7 @@ bool IsUserAuthorizedGloballyLabels(const memgraph::auth::User &user,
|
|||||||
|
|
||||||
bool IsUserAuthorizedGloballyEdges(const memgraph::auth::User &user,
|
bool IsUserAuthorizedGloballyEdges(const memgraph::auth::User &user,
|
||||||
const memgraph::auth::FineGrainedPermission fine_grained_permission) {
|
const memgraph::auth::FineGrainedPermission fine_grained_permission) {
|
||||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return user.GetFineGrainedAccessEdgeTypePermissions().Has(memgraph::auth::kAsterisk, fine_grained_permission) ==
|
return user.GetFineGrainedAccessEdgeTypePermissions().Has(memgraph::auth::kAsterisk, fine_grained_permission) ==
|
||||||
@ -54,7 +54,7 @@ bool IsUserAuthorizedGloballyEdges(const memgraph::auth::User &user,
|
|||||||
bool IsUserAuthorizedEdgeType(const memgraph::auth::User &user, const memgraph::query::DbAccessor *dba,
|
bool IsUserAuthorizedEdgeType(const memgraph::auth::User &user, const memgraph::query::DbAccessor *dba,
|
||||||
const memgraph::storage::EdgeTypeId &edgeType,
|
const memgraph::storage::EdgeTypeId &edgeType,
|
||||||
const memgraph::query::AuthQuery::FineGrainedPrivilege fine_grained_privilege) {
|
const memgraph::query::AuthQuery::FineGrainedPrivilege fine_grained_privilege) {
|
||||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return user.GetFineGrainedAccessEdgeTypePermissions().Has(
|
return user.GetFineGrainedAccessEdgeTypePermissions().Has(
|
||||||
@ -87,7 +87,7 @@ bool AuthChecker::IsUserAuthorized(const std::optional<std::string> &username,
|
|||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
std::unique_ptr<memgraph::query::FineGrainedAuthChecker> AuthChecker::GetFineGrainedAuthChecker(
|
std::unique_ptr<memgraph::query::FineGrainedAuthChecker> AuthChecker::GetFineGrainedAuthChecker(
|
||||||
const std::string &username, const memgraph::query::DbAccessor *dba) const {
|
const std::string &username, const memgraph::query::DbAccessor *dba) const {
|
||||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@ -154,7 +154,7 @@ bool FineGrainedAuthChecker::Has(const memgraph::storage::EdgeTypeId &edge_type,
|
|||||||
|
|
||||||
bool FineGrainedAuthChecker::HasGlobalPrivilegeOnVertices(
|
bool FineGrainedAuthChecker::HasGlobalPrivilegeOnVertices(
|
||||||
const memgraph::query::AuthQuery::FineGrainedPrivilege fine_grained_privilege) const {
|
const memgraph::query::AuthQuery::FineGrainedPrivilege fine_grained_privilege) const {
|
||||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return IsUserAuthorizedGloballyLabels(user_, FineGrainedPrivilegeToFineGrainedPermission(fine_grained_privilege));
|
return IsUserAuthorizedGloballyLabels(user_, FineGrainedPrivilegeToFineGrainedPermission(fine_grained_privilege));
|
||||||
@ -162,7 +162,7 @@ bool FineGrainedAuthChecker::HasGlobalPrivilegeOnVertices(
|
|||||||
|
|
||||||
bool FineGrainedAuthChecker::HasGlobalPrivilegeOnEdges(
|
bool FineGrainedAuthChecker::HasGlobalPrivilegeOnEdges(
|
||||||
const memgraph::query::AuthQuery::FineGrainedPrivilege fine_grained_privilege) const {
|
const memgraph::query::AuthQuery::FineGrainedPrivilege fine_grained_privilege) const {
|
||||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return IsUserAuthorizedGloballyEdges(user_, FineGrainedPrivilegeToFineGrainedPermission(fine_grained_privilege));
|
return IsUserAuthorizedGloballyEdges(user_, FineGrainedPrivilegeToFineGrainedPermission(fine_grained_privilege));
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
#include "auth/models.hpp"
|
#include "auth/models.hpp"
|
||||||
#include "glue/auth.hpp"
|
#include "glue/auth.hpp"
|
||||||
#include "utils/license.hpp"
|
#include "license/license.hpp"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@ -125,7 +125,7 @@ std::vector<FineGrainedPermissionForPrivilegeResult> GetFineGrainedPermissionFor
|
|||||||
const memgraph::auth::FineGrainedAccessPermissions &permissions, const std::string &permission_type,
|
const memgraph::auth::FineGrainedAccessPermissions &permissions, const std::string &permission_type,
|
||||||
const std::string &user_or_role) {
|
const std::string &user_or_role) {
|
||||||
std::vector<FineGrainedPermissionForPrivilegeResult> fine_grained_permissions;
|
std::vector<FineGrainedPermissionForPrivilegeResult> fine_grained_permissions;
|
||||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
return fine_grained_permissions;
|
return fine_grained_permissions;
|
||||||
}
|
}
|
||||||
const auto global_permission = permissions.GetGlobalPermission();
|
const auto global_permission = permissions.GetGlobalPermission();
|
||||||
@ -166,7 +166,7 @@ std::vector<FineGrainedPermissionForPrivilegeResult> GetFineGrainedPermissionFor
|
|||||||
std::vector<std::vector<memgraph::query::TypedValue>> ConstructFineGrainedPrivilegesResult(
|
std::vector<std::vector<memgraph::query::TypedValue>> ConstructFineGrainedPrivilegesResult(
|
||||||
const std::vector<FineGrainedPermissionForPrivilegeResult> &privileges) {
|
const std::vector<FineGrainedPermissionForPrivilegeResult> &privileges) {
|
||||||
std::vector<std::vector<memgraph::query::TypedValue>> grants;
|
std::vector<std::vector<memgraph::query::TypedValue>> grants;
|
||||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
grants.reserve(privileges.size());
|
grants.reserve(privileges.size());
|
||||||
@ -182,7 +182,7 @@ std::vector<std::vector<memgraph::query::TypedValue>> ConstructFineGrainedPrivil
|
|||||||
|
|
||||||
std::vector<std::vector<memgraph::query::TypedValue>> ShowFineGrainedUserPrivileges(
|
std::vector<std::vector<memgraph::query::TypedValue>> ShowFineGrainedUserPrivileges(
|
||||||
const std::optional<memgraph::auth::User> &user) {
|
const std::optional<memgraph::auth::User> &user) {
|
||||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
const auto &label_permissions = user->GetFineGrainedAccessLabelPermissions();
|
const auto &label_permissions = user->GetFineGrainedAccessLabelPermissions();
|
||||||
@ -201,7 +201,7 @@ std::vector<std::vector<memgraph::query::TypedValue>> ShowFineGrainedUserPrivile
|
|||||||
|
|
||||||
std::vector<std::vector<memgraph::query::TypedValue>> ShowFineGrainedRolePrivileges(
|
std::vector<std::vector<memgraph::query::TypedValue>> ShowFineGrainedRolePrivileges(
|
||||||
const std::optional<memgraph::auth::Role> &role) {
|
const std::optional<memgraph::auth::Role> &role) {
|
||||||
if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (!memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
const auto &label_permissions = role->GetFineGrainedAccessLabelPermissions();
|
const auto &label_permissions = role->GetFineGrainedAccessLabelPermissions();
|
||||||
@ -231,13 +231,13 @@ AuthQueryHandler::AuthQueryHandler(
|
|||||||
bool AuthQueryHandler::CreateUser(const std::string &username, const std::optional<std::string> &password) {
|
bool AuthQueryHandler::CreateUser(const std::string &username, const std::optional<std::string> &password) {
|
||||||
if (name_regex_string_ != kDefaultUserRoleRegex) {
|
if (name_regex_string_ != kDefaultUserRoleRegex) {
|
||||||
if (const auto license_check_result =
|
if (const auto license_check_result =
|
||||||
memgraph::utils::license::global_license_checker.IsValidLicense(memgraph::utils::global_settings);
|
memgraph::license::global_license_checker.IsEnterpriseValid(memgraph::utils::global_settings);
|
||||||
license_check_result.HasError()) {
|
license_check_result.HasError()) {
|
||||||
throw memgraph::auth::AuthException(
|
throw memgraph::auth::AuthException(
|
||||||
"Custom user/role regex is a Memgraph Enterprise feature. Please set the config "
|
"Custom user/role regex is a Memgraph Enterprise feature. Please set the config "
|
||||||
"(\"--auth-user-or-role-name-regex\") to its default value (\"{}\") or remove the flag.\n{}",
|
"(\"--auth-user-or-role-name-regex\") to its default value (\"{}\") or remove the flag.\n{}",
|
||||||
kDefaultUserRoleRegex,
|
kDefaultUserRoleRegex,
|
||||||
memgraph::utils::license::LicenseCheckErrorToString(license_check_result.GetError(), "user/role regex"));
|
memgraph::license::LicenseCheckErrorToString(license_check_result.GetError(), "user/role regex"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!std::regex_match(username, name_regex_)) {
|
if (!std::regex_match(username, name_regex_)) {
|
||||||
@ -473,20 +473,20 @@ std::vector<std::vector<memgraph::query::TypedValue>> AuthQueryHandler::GetPrivi
|
|||||||
if (user) {
|
if (user) {
|
||||||
grants = ShowUserPrivileges(user);
|
grants = ShowUserPrivileges(user);
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
fine_grained_grants = ShowFineGrainedUserPrivileges(user);
|
fine_grained_grants = ShowFineGrainedUserPrivileges(user);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
grants = ShowRolePrivileges(role);
|
grants = ShowRolePrivileges(role);
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
fine_grained_grants = ShowFineGrainedRolePrivileges(role);
|
fine_grained_grants = ShowFineGrainedRolePrivileges(role);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
grants.insert(grants.end(), fine_grained_grants.begin(), fine_grained_grants.end());
|
grants.insert(grants.end(), fine_grained_grants.begin(), fine_grained_grants.end());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -627,7 +627,7 @@ void AuthQueryHandler::EditPermissions(
|
|||||||
edit_permissions_fun(user->permissions(), permission);
|
edit_permissions_fun(user->permissions(), permission);
|
||||||
}
|
}
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
for (const auto &label_privilege_collection : label_privileges) {
|
for (const auto &label_privilege_collection : label_privileges) {
|
||||||
edit_fine_grained_permissions_fun(user->fine_grained_access_handler().label_permissions(),
|
edit_fine_grained_permissions_fun(user->fine_grained_access_handler().label_permissions(),
|
||||||
label_privilege_collection);
|
label_privilege_collection);
|
||||||
@ -644,7 +644,7 @@ void AuthQueryHandler::EditPermissions(
|
|||||||
edit_permissions_fun(role->permissions(), permission);
|
edit_permissions_fun(role->permissions(), permission);
|
||||||
}
|
}
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
for (const auto &label_privilege : label_privileges) {
|
for (const auto &label_privilege : label_privileges) {
|
||||||
edit_fine_grained_permissions_fun(role->fine_grained_access_handler().label_permissions(), label_privilege);
|
edit_fine_grained_permissions_fun(role->fine_grained_access_handler().label_permissions(), label_privilege);
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
|
|
||||||
#include "auth/auth.hpp"
|
#include "auth/auth.hpp"
|
||||||
#include "glue/auth.hpp"
|
#include "glue/auth.hpp"
|
||||||
|
#include "license/license.hpp"
|
||||||
#include "query/interpreter.hpp"
|
#include "query/interpreter.hpp"
|
||||||
#include "utils/license.hpp"
|
|
||||||
#include "utils/string.hpp"
|
#include "utils/string.hpp"
|
||||||
|
|
||||||
namespace memgraph::glue {
|
namespace memgraph::glue {
|
||||||
|
6
src/license/CMakeLists.txt
Normal file
6
src/license/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
set(license_src_files
|
||||||
|
license_sender.cpp
|
||||||
|
license.cpp)
|
||||||
|
add_library(mg-license STATIC ${license_src_files})
|
||||||
|
|
||||||
|
target_link_libraries(mg-license mg-settings mg-utils mg-requests spdlog::spdlog)
|
@ -9,17 +9,19 @@
|
|||||||
// by the Apache License, Version 2.0, included in the file
|
// by the Apache License, Version 2.0, included in the file
|
||||||
// licenses/APL.txt.
|
// licenses/APL.txt.
|
||||||
|
|
||||||
#include "utils/license.hpp"
|
#include "license/license.hpp"
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <charconv>
|
#include <charconv>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <cstdint>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "slk/serialization.hpp"
|
#include "slk/serialization.hpp"
|
||||||
#include "utils/base64.hpp"
|
#include "utils/base64.hpp"
|
||||||
|
#include "utils/cast.hpp"
|
||||||
#include "utils/exceptions.hpp"
|
#include "utils/exceptions.hpp"
|
||||||
#include "utils/logging.hpp"
|
#include "utils/logging.hpp"
|
||||||
#include "utils/memory_tracker.hpp"
|
#include "utils/memory_tracker.hpp"
|
||||||
@ -27,7 +29,7 @@
|
|||||||
#include "utils/spin_lock.hpp"
|
#include "utils/spin_lock.hpp"
|
||||||
#include "utils/synchronized.hpp"
|
#include "utils/synchronized.hpp"
|
||||||
|
|
||||||
namespace memgraph::utils::license {
|
namespace memgraph::license {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
inline constexpr std::string_view license_key_prefix = "mglk-";
|
inline constexpr std::string_view license_key_prefix = "mglk-";
|
||||||
@ -69,6 +71,17 @@ LicenseCheckResult IsValidLicenseInternal(const License &license, const std::str
|
|||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
std::string LicenseTypeToString(const LicenseType license_type) {
|
||||||
|
switch (license_type) {
|
||||||
|
case LicenseType::ENTERPRISE: {
|
||||||
|
return "enterprise";
|
||||||
|
}
|
||||||
|
case LicenseType::OEM: {
|
||||||
|
return "oem";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RegisterLicenseSettings(LicenseChecker &license_checker, utils::Settings &settings) {
|
void RegisterLicenseSettings(LicenseChecker &license_checker, utils::Settings &settings) {
|
||||||
settings.RegisterSetting(std::string{kEnterpriseLicenseSettingKey}, "",
|
settings.RegisterSetting(std::string{kEnterpriseLicenseSettingKey}, "",
|
||||||
[&] { license_checker.RevalidateLicense(settings); });
|
[&] { license_checker.RevalidateLicense(settings); });
|
||||||
@ -81,7 +94,7 @@ LicenseChecker global_license_checker;
|
|||||||
|
|
||||||
LicenseChecker::~LicenseChecker() { scheduler_.Stop(); }
|
LicenseChecker::~LicenseChecker() { scheduler_.Stop(); }
|
||||||
|
|
||||||
std::pair<std::string, std::string> LicenseChecker::GetLicenseInfo(const utils::Settings &settings) const {
|
std::pair<std::string, std::string> LicenseChecker::ExtractLicenseInfo(const utils::Settings &settings) const {
|
||||||
if (license_info_override_) {
|
if (license_info_override_) {
|
||||||
spdlog::warn("Ignoring license info stored in the settings because a different source was specified.");
|
spdlog::warn("Ignoring license info stored in the settings because a different source was specified.");
|
||||||
return *license_info_override_;
|
return *license_info_override_;
|
||||||
@ -96,7 +109,7 @@ std::pair<std::string, std::string> LicenseChecker::GetLicenseInfo(const utils::
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LicenseChecker::RevalidateLicense(const utils::Settings &settings) {
|
void LicenseChecker::RevalidateLicense(const utils::Settings &settings) {
|
||||||
const auto license_info = GetLicenseInfo(settings);
|
const auto license_info = ExtractLicenseInfo(settings);
|
||||||
RevalidateLicense(license_info.first, license_info.second);
|
RevalidateLicense(license_info.first, license_info.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,18 +130,7 @@ void LicenseChecker::RevalidateLicense(const std::string &license_key, const std
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PreviousLicenseInfo {
|
auto locked_previous_license_info_ptr = previous_license_info_.Lock();
|
||||||
PreviousLicenseInfo(std::string license_key, std::string organization_name)
|
|
||||||
: license_key(std::move(license_key)), organization_name(std::move(organization_name)) {}
|
|
||||||
|
|
||||||
std::string license_key;
|
|
||||||
std::string organization_name;
|
|
||||||
bool is_valid{false};
|
|
||||||
};
|
|
||||||
|
|
||||||
static utils::Synchronized<std::optional<PreviousLicenseInfo>, utils::SpinLock> previous_license_info;
|
|
||||||
|
|
||||||
auto locked_previous_license_info_ptr = previous_license_info.Lock();
|
|
||||||
auto &locked_previous_license_info = *locked_previous_license_info_ptr;
|
auto &locked_previous_license_info = *locked_previous_license_info_ptr;
|
||||||
const bool same_license_info = locked_previous_license_info &&
|
const bool same_license_info = locked_previous_license_info &&
|
||||||
locked_previous_license_info->license_key == license_key &&
|
locked_previous_license_info->license_key == license_key &&
|
||||||
@ -140,7 +142,7 @@ void LicenseChecker::RevalidateLicense(const std::string &license_key, const std
|
|||||||
|
|
||||||
locked_previous_license_info.emplace(license_key, organization_name);
|
locked_previous_license_info.emplace(license_key, organization_name);
|
||||||
|
|
||||||
const auto maybe_license = GetLicense(locked_previous_license_info->license_key);
|
auto maybe_license = GetLicense(locked_previous_license_info->license_key);
|
||||||
if (!maybe_license) {
|
if (!maybe_license) {
|
||||||
spdlog::warn(LicenseCheckErrorToString(LicenseCheckError::INVALID_LICENSE_KEY_STRING, "Enterprise features"));
|
spdlog::warn(LicenseCheckErrorToString(LicenseCheckError::INVALID_LICENSE_KEY_STRING, "Enterprise features"));
|
||||||
is_valid_.store(false, std::memory_order_relaxed);
|
is_valid_.store(false, std::memory_order_relaxed);
|
||||||
@ -156,22 +158,30 @@ void LicenseChecker::RevalidateLicense(const std::string &license_key, const std
|
|||||||
spdlog::warn(LicenseCheckErrorToString(license_check_result.GetError(), "Enterprise features"));
|
spdlog::warn(LicenseCheckErrorToString(license_check_result.GetError(), "Enterprise features"));
|
||||||
is_valid_.store(false, std::memory_order_relaxed);
|
is_valid_.store(false, std::memory_order_relaxed);
|
||||||
locked_previous_license_info->is_valid = false;
|
locked_previous_license_info->is_valid = false;
|
||||||
|
license_type_ = maybe_license->type;
|
||||||
set_memory_limit(0);
|
set_memory_limit(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!same_license_info) {
|
if (!same_license_info) {
|
||||||
spdlog::info("All Enterprise features are active.");
|
license_type_ = maybe_license->type;
|
||||||
|
if (license_type_ == LicenseType::ENTERPRISE) {
|
||||||
|
spdlog::info("Enterprise license is active.");
|
||||||
|
} else {
|
||||||
|
spdlog::info("OEM license is active.");
|
||||||
|
}
|
||||||
is_valid_.store(true, std::memory_order_relaxed);
|
is_valid_.store(true, std::memory_order_relaxed);
|
||||||
locked_previous_license_info->is_valid = true;
|
locked_previous_license_info->is_valid = true;
|
||||||
set_memory_limit(maybe_license->memory_limit);
|
set_memory_limit(maybe_license->memory_limit);
|
||||||
|
locked_previous_license_info->license = std::move(*maybe_license);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LicenseChecker::EnableTesting() {
|
void LicenseChecker::EnableTesting(const LicenseType license_type) {
|
||||||
enterprise_enabled_ = true;
|
enterprise_enabled_ = true;
|
||||||
is_valid_.store(true, std::memory_order_relaxed);
|
is_valid_.store(true, std::memory_order_relaxed);
|
||||||
spdlog::info("All Enterprise features are activated for testing.");
|
license_type_ = license_type;
|
||||||
|
spdlog::info("The license type {} is set for testing.", LicenseTypeToString(license_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LicenseChecker::CheckEnvLicense() {
|
void LicenseChecker::CheckEnvLicense() {
|
||||||
@ -216,20 +226,26 @@ std::string LicenseCheckErrorToString(LicenseCheckError error, const std::string
|
|||||||
"following query:\n"
|
"following query:\n"
|
||||||
"SET DATABASE SETTING \"enterprise.license\" TO \"your-license-key\"",
|
"SET DATABASE SETTING \"enterprise.license\" TO \"your-license-key\"",
|
||||||
feature);
|
feature);
|
||||||
|
case LicenseCheckError::NOT_ENTERPRISE_LICENSE:
|
||||||
|
return fmt::format("Your license has an invalid type. To use {} you need to have an enterprise license. \n",
|
||||||
|
feature);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LicenseCheckResult LicenseChecker::IsValidLicense(const utils::Settings &settings) const {
|
LicenseCheckResult LicenseChecker::IsEnterpriseValid(const utils::Settings &settings) const {
|
||||||
if (enterprise_enabled_) [[unlikely]] {
|
if (enterprise_enabled_) [[unlikely]] {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto license_info = GetLicenseInfo(settings);
|
const auto license_info = ExtractLicenseInfo(settings);
|
||||||
|
|
||||||
const auto maybe_license = GetLicense(license_info.first);
|
const auto maybe_license = GetLicense(license_info.first);
|
||||||
if (!maybe_license) {
|
if (!maybe_license) {
|
||||||
return LicenseCheckError::INVALID_LICENSE_KEY_STRING;
|
return LicenseCheckError::INVALID_LICENSE_KEY_STRING;
|
||||||
}
|
}
|
||||||
|
if (maybe_license->type != LicenseType::ENTERPRISE) {
|
||||||
|
return LicenseCheckError::NOT_ENTERPRISE_LICENSE;
|
||||||
|
}
|
||||||
|
|
||||||
return IsValidLicenseInternal(*maybe_license, license_info.second);
|
return IsValidLicenseInternal(*maybe_license, license_info.second);
|
||||||
}
|
}
|
||||||
@ -239,7 +255,13 @@ void LicenseChecker::StartBackgroundLicenseChecker(const utils::Settings &settin
|
|||||||
scheduler_.Run("licensechecker", std::chrono::minutes{5}, [&, this] { RevalidateLicense(settings); });
|
scheduler_.Run("licensechecker", std::chrono::minutes{5}, [&, this] { RevalidateLicense(settings); });
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LicenseChecker::IsValidLicenseFast() const { return is_valid_.load(std::memory_order_relaxed); }
|
utils::Synchronized<std::optional<LicenseInfo>, utils::SpinLock> &LicenseChecker::GetLicenseInfo() {
|
||||||
|
return previous_license_info_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LicenseChecker::IsEnterpriseValidFast() const {
|
||||||
|
return license_type_ == LicenseType::ENTERPRISE && is_valid_.load(std::memory_order_relaxed);
|
||||||
|
}
|
||||||
|
|
||||||
std::string Encode(const License &license) {
|
std::string Encode(const License &license) {
|
||||||
std::vector<uint8_t> buffer;
|
std::vector<uint8_t> buffer;
|
||||||
@ -252,9 +274,10 @@ std::string Encode(const License &license) {
|
|||||||
slk::Save(license.organization_name, &builder);
|
slk::Save(license.organization_name, &builder);
|
||||||
slk::Save(license.valid_until, &builder);
|
slk::Save(license.valid_until, &builder);
|
||||||
slk::Save(license.memory_limit, &builder);
|
slk::Save(license.memory_limit, &builder);
|
||||||
|
slk::Save(utils::UnderlyingCast(license.type), &builder);
|
||||||
builder.Finalize();
|
builder.Finalize();
|
||||||
|
|
||||||
return std::string{license_key_prefix} + base64_encode(buffer.data(), buffer.size());
|
return std::string{license_key_prefix} + utils::base64_encode(buffer.data(), buffer.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<License> Decode(std::string_view license_key) {
|
std::optional<License> Decode(std::string_view license_key) {
|
||||||
@ -266,7 +289,7 @@ std::optional<License> Decode(std::string_view license_key) {
|
|||||||
|
|
||||||
const auto decoded = std::invoke([license_key]() -> std::optional<std::string> {
|
const auto decoded = std::invoke([license_key]() -> std::optional<std::string> {
|
||||||
try {
|
try {
|
||||||
return base64_decode(license_key);
|
return utils::base64_decode(license_key);
|
||||||
} catch (const std::runtime_error & /*exception*/) {
|
} catch (const std::runtime_error & /*exception*/) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
@ -284,10 +307,12 @@ std::optional<License> Decode(std::string_view license_key) {
|
|||||||
slk::Load(&valid_until, &reader);
|
slk::Load(&valid_until, &reader);
|
||||||
int64_t memory_limit{0};
|
int64_t memory_limit{0};
|
||||||
slk::Load(&memory_limit, &reader);
|
slk::Load(&memory_limit, &reader);
|
||||||
return License{.organization_name = organization_name, .valid_until = valid_until, .memory_limit = memory_limit};
|
std::underlying_type_t<LicenseType> license_type{0};
|
||||||
|
slk::Load(&license_type, &reader);
|
||||||
|
return {License{organization_name, valid_until, memory_limit, LicenseType(license_type)}};
|
||||||
} catch (const slk::SlkReaderException &e) {
|
} catch (const slk::SlkReaderException &e) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace memgraph::utils::license
|
} // namespace memgraph::license
|
@ -12,26 +12,57 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "utils/result.hpp"
|
#include "utils/result.hpp"
|
||||||
#include "utils/scheduler.hpp"
|
#include "utils/scheduler.hpp"
|
||||||
#include "utils/settings.hpp"
|
#include "utils/settings.hpp"
|
||||||
|
#include "utils/spin_lock.hpp"
|
||||||
|
#include "utils/synchronized.hpp"
|
||||||
|
|
||||||
namespace memgraph::utils::license {
|
namespace memgraph::license {
|
||||||
|
|
||||||
|
enum class LicenseType : uint8_t { ENTERPRISE, OEM };
|
||||||
|
|
||||||
|
std::string LicenseTypeToString(LicenseType license_type);
|
||||||
|
|
||||||
struct License {
|
struct License {
|
||||||
|
License() = default;
|
||||||
|
|
||||||
|
License(std::string organization_name, int64_t valid_until, int64_t memory_limit, LicenseType license_type)
|
||||||
|
: organization_name{std::move(organization_name)},
|
||||||
|
valid_until{valid_until},
|
||||||
|
memory_limit{memory_limit},
|
||||||
|
type{license_type} {}
|
||||||
|
|
||||||
std::string organization_name;
|
std::string organization_name;
|
||||||
int64_t valid_until;
|
int64_t valid_until;
|
||||||
int64_t memory_limit;
|
int64_t memory_limit;
|
||||||
|
LicenseType type;
|
||||||
|
|
||||||
bool operator==(const License &) const = default;
|
bool operator==(const License &) const = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct LicenseInfo {
|
||||||
|
LicenseInfo(std::string license_key, std::string organization_name)
|
||||||
|
: license_key(std::move(license_key)), organization_name{std::move(organization_name)} {}
|
||||||
|
|
||||||
|
std::string license_key;
|
||||||
|
std::string organization_name;
|
||||||
|
bool is_valid{false};
|
||||||
|
License license;
|
||||||
|
};
|
||||||
|
|
||||||
inline constexpr std::string_view kEnterpriseLicenseSettingKey = "enterprise.license";
|
inline constexpr std::string_view kEnterpriseLicenseSettingKey = "enterprise.license";
|
||||||
inline constexpr std::string_view kOrganizationNameSettingKey = "organization.name";
|
inline constexpr std::string_view kOrganizationNameSettingKey = "organization.name";
|
||||||
|
|
||||||
enum class LicenseCheckError : uint8_t { INVALID_LICENSE_KEY_STRING, INVALID_ORGANIZATION_NAME, EXPIRED_LICENSE };
|
enum class LicenseCheckError : uint8_t {
|
||||||
|
INVALID_LICENSE_KEY_STRING,
|
||||||
|
INVALID_ORGANIZATION_NAME,
|
||||||
|
EXPIRED_LICENSE,
|
||||||
|
NOT_ENTERPRISE_LICENSE
|
||||||
|
};
|
||||||
|
|
||||||
std::string LicenseCheckErrorToString(LicenseCheckError error, std::string_view feature);
|
std::string LicenseCheckErrorToString(LicenseCheckError error, std::string_view feature);
|
||||||
|
|
||||||
@ -49,19 +80,25 @@ struct LicenseChecker {
|
|||||||
|
|
||||||
void CheckEnvLicense();
|
void CheckEnvLicense();
|
||||||
void SetLicenseInfoOverride(std::string license_key, std::string organization_name);
|
void SetLicenseInfoOverride(std::string license_key, std::string organization_name);
|
||||||
void EnableTesting();
|
void EnableTesting(LicenseType license_type = LicenseType::ENTERPRISE);
|
||||||
LicenseCheckResult IsValidLicense(const utils::Settings &settings) const;
|
// Checks if license is valid and if enterprise is enabled
|
||||||
bool IsValidLicenseFast() const;
|
LicenseCheckResult IsEnterpriseValid(const utils::Settings &settings) const;
|
||||||
|
bool IsEnterpriseValidFast() const;
|
||||||
|
|
||||||
void StartBackgroundLicenseChecker(const utils::Settings &settings);
|
void StartBackgroundLicenseChecker(const utils::Settings &settings);
|
||||||
|
|
||||||
|
utils::Synchronized<std::optional<LicenseInfo>, utils::SpinLock> &GetLicenseInfo();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::pair<std::string, std::string> GetLicenseInfo(const utils::Settings &settings) const;
|
std::pair<std::string, std::string> ExtractLicenseInfo(const utils::Settings &settings) const;
|
||||||
void RevalidateLicense(const utils::Settings &settings);
|
void RevalidateLicense(const utils::Settings &settings);
|
||||||
void RevalidateLicense(const std::string &license_key, const std::string &organization_name);
|
void RevalidateLicense(const std::string &license_key, const std::string &organization_name);
|
||||||
|
|
||||||
std::optional<std::pair<std::string, std::string>> license_info_override_;
|
std::optional<std::pair<std::string, std::string>> license_info_override_;
|
||||||
|
utils::Synchronized<std::optional<LicenseInfo>, utils::SpinLock> previous_license_info_{std::nullopt};
|
||||||
bool enterprise_enabled_{false};
|
bool enterprise_enabled_{false};
|
||||||
std::atomic<bool> is_valid_{false};
|
std::atomic<bool> is_valid_{false};
|
||||||
|
LicenseType license_type_;
|
||||||
utils::Scheduler scheduler_;
|
utils::Scheduler scheduler_;
|
||||||
|
|
||||||
friend void RegisterLicenseSettings(LicenseChecker &license_checker, utils::Settings &settings);
|
friend void RegisterLicenseSettings(LicenseChecker &license_checker, utils::Settings &settings);
|
||||||
@ -74,4 +111,4 @@ std::string Encode(const License &license);
|
|||||||
|
|
||||||
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
|
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
|
||||||
extern LicenseChecker global_license_checker;
|
extern LicenseChecker global_license_checker;
|
||||||
} // namespace memgraph::utils::license
|
} // namespace memgraph::license
|
71
src/license/license_sender.cpp
Normal file
71
src/license/license_sender.cpp
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
// Copyright 2022 Memgraph Ltd.
|
||||||
|
//
|
||||||
|
// Use of this software is governed by the Business Source License
|
||||||
|
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||||
|
// License, and you may not use this file except in compliance with the Business Source License.
|
||||||
|
//
|
||||||
|
// As of the Change Date specified in that file, in accordance with
|
||||||
|
// the Business Source License, use of this software will be governed
|
||||||
|
// by the Apache License, Version 2.0, included in the file
|
||||||
|
// licenses/APL.txt.
|
||||||
|
|
||||||
|
#include "license/license_sender.hpp"
|
||||||
|
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "requests/requests.hpp"
|
||||||
|
#include "utils/memory_tracker.hpp"
|
||||||
|
#include "utils/stat.hpp"
|
||||||
|
#include "utils/synchronized.hpp"
|
||||||
|
#include "utils/system_info.hpp"
|
||||||
|
#include "utils/timestamp.hpp"
|
||||||
|
|
||||||
|
namespace memgraph::license {
|
||||||
|
|
||||||
|
LicenseInfoSender::LicenseInfoSender(std::string url, std::string uuid, std::string machine_id, int64_t memory_limit,
|
||||||
|
utils::Synchronized<std::optional<LicenseInfo>, utils::SpinLock> &license_info,
|
||||||
|
std::chrono::seconds request_frequency)
|
||||||
|
: url_{std::move(url)},
|
||||||
|
uuid_{std::move(uuid)},
|
||||||
|
machine_id_{std::move(machine_id)},
|
||||||
|
memory_limit_{memory_limit},
|
||||||
|
license_info_{license_info} {
|
||||||
|
scheduler_.Run("LicenseCheck", request_frequency, [&] { SendData(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
LicenseInfoSender::~LicenseInfoSender() { scheduler_.Stop(); }
|
||||||
|
|
||||||
|
void LicenseInfoSender::SendData() {
|
||||||
|
nlohmann::json data = nlohmann::json::object();
|
||||||
|
|
||||||
|
license_info_.WithLock([&data, this](const auto &license_info) mutable {
|
||||||
|
if (license_info && !license_info->organization_name.empty()) {
|
||||||
|
const auto memory_info = utils::GetMemoryInfo();
|
||||||
|
const auto memory_usage = utils::GetMemoryUsage();
|
||||||
|
data = {{"run_id", uuid_},
|
||||||
|
{"machine_id", machine_id_},
|
||||||
|
{"type", "license-check"},
|
||||||
|
{"license_type", LicenseTypeToString(license_info->license.type)},
|
||||||
|
{"license_key", license_info->license_key},
|
||||||
|
{"organization", license_info->organization_name},
|
||||||
|
{"valid", license_info->is_valid},
|
||||||
|
{"physical_memory_size", memory_info.memory},
|
||||||
|
{"swap_memory_size", memory_info.swap},
|
||||||
|
{"memory_used", memory_usage},
|
||||||
|
{"runtime_memory_limit", memory_limit_},
|
||||||
|
{"license_memory_limit", license_info->license.memory_limit},
|
||||||
|
{"timestamp", utils::Timestamp::Now().SecWithNsecSinceTheEpoch()}};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (data.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!requests::RequestPostJson(url_, data,
|
||||||
|
/* timeout_in_seconds = */ 2 * 60)) {
|
||||||
|
spdlog::trace("Cannot send license information, enable {} availability!", url_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace memgraph::license
|
50
src/license/license_sender.hpp
Normal file
50
src/license/license_sender.hpp
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// Copyright 2022 Memgraph Ltd.
|
||||||
|
//
|
||||||
|
// Use of this software is governed by the Business Source License
|
||||||
|
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||||
|
// License, and you may not use this file except in compliance with the Business Source License.
|
||||||
|
//
|
||||||
|
// As of the Change Date specified in that file, in accordance with
|
||||||
|
// the Business Source License, use of this software will be governed
|
||||||
|
// by the Apache License, Version 2.0, included in the file
|
||||||
|
// licenses/APL.txt.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <json/json.hpp>
|
||||||
|
|
||||||
|
#include "license/license.hpp"
|
||||||
|
#include "utils/scheduler.hpp"
|
||||||
|
#include "utils/timer.hpp"
|
||||||
|
|
||||||
|
namespace memgraph::license {
|
||||||
|
|
||||||
|
class LicenseInfoSender final {
|
||||||
|
public:
|
||||||
|
LicenseInfoSender(std::string url, std::string uuid, std::string machine_id, int64_t memory_limit,
|
||||||
|
utils::Synchronized<std::optional<LicenseInfo>, utils::SpinLock> &license_info,
|
||||||
|
std::chrono::seconds request_frequency = std::chrono::seconds(8 * 60 * 60));
|
||||||
|
|
||||||
|
LicenseInfoSender(const LicenseInfoSender &) = delete;
|
||||||
|
LicenseInfoSender(LicenseInfoSender &&) noexcept = delete;
|
||||||
|
LicenseInfoSender &operator=(const LicenseInfoSender &) = delete;
|
||||||
|
LicenseInfoSender &operator=(LicenseInfoSender &&) noexcept = delete;
|
||||||
|
~LicenseInfoSender();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SendData();
|
||||||
|
|
||||||
|
const std::string url_;
|
||||||
|
const std::string uuid_;
|
||||||
|
const std::string machine_id_;
|
||||||
|
const int64_t memory_limit_;
|
||||||
|
|
||||||
|
utils::Synchronized<std::optional<LicenseInfo>, utils::SpinLock> &license_info_;
|
||||||
|
utils::Scheduler scheduler_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace memgraph::license
|
@ -40,6 +40,8 @@
|
|||||||
#include "glue/auth_checker.hpp"
|
#include "glue/auth_checker.hpp"
|
||||||
#include "glue/auth_handler.hpp"
|
#include "glue/auth_handler.hpp"
|
||||||
#include "helpers.hpp"
|
#include "helpers.hpp"
|
||||||
|
#include "license/license.hpp"
|
||||||
|
#include "license/license_sender.hpp"
|
||||||
#include "py/py.hpp"
|
#include "py/py.hpp"
|
||||||
#include "query/auth_checker.hpp"
|
#include "query/auth_checker.hpp"
|
||||||
#include "query/discard_value_stream.hpp"
|
#include "query/discard_value_stream.hpp"
|
||||||
@ -57,7 +59,6 @@
|
|||||||
#include "utils/event_counter.hpp"
|
#include "utils/event_counter.hpp"
|
||||||
#include "utils/file.hpp"
|
#include "utils/file.hpp"
|
||||||
#include "utils/flag_validation.hpp"
|
#include "utils/flag_validation.hpp"
|
||||||
#include "utils/license.hpp"
|
|
||||||
#include "utils/logging.hpp"
|
#include "utils/logging.hpp"
|
||||||
#include "utils/memory_tracker.hpp"
|
#include "utils/memory_tracker.hpp"
|
||||||
#include "utils/message.hpp"
|
#include "utils/message.hpp"
|
||||||
@ -68,6 +69,7 @@
|
|||||||
#include "utils/string.hpp"
|
#include "utils/string.hpp"
|
||||||
#include "utils/synchronized.hpp"
|
#include "utils/synchronized.hpp"
|
||||||
#include "utils/sysinfo/memory.hpp"
|
#include "utils/sysinfo/memory.hpp"
|
||||||
|
#include "utils/system_info.hpp"
|
||||||
#include "utils/terminate_handler.hpp"
|
#include "utils/terminate_handler.hpp"
|
||||||
#include "version.hpp"
|
#include "version.hpp"
|
||||||
|
|
||||||
@ -506,7 +508,7 @@ class BoltSession final : public memgraph::communication::bolt::Session<memgraph
|
|||||||
username = &user_->username();
|
username = &user_->username();
|
||||||
}
|
}
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
audit_log_->Record(endpoint_.address().to_string(), user_ ? *username : "", query,
|
audit_log_->Record(endpoint_.address().to_string(), user_ ? *username : "", query,
|
||||||
memgraph::storage::PropertyValue(params_pv));
|
memgraph::storage::PropertyValue(params_pv));
|
||||||
}
|
}
|
||||||
@ -779,15 +781,15 @@ int main(int argc, char **argv) {
|
|||||||
memgraph::utils::OnScopeExit settings_finalizer([&] { memgraph::utils::global_settings.Finalize(); });
|
memgraph::utils::OnScopeExit settings_finalizer([&] { memgraph::utils::global_settings.Finalize(); });
|
||||||
|
|
||||||
// register all runtime settings
|
// register all runtime settings
|
||||||
memgraph::utils::license::RegisterLicenseSettings(memgraph::utils::license::global_license_checker,
|
memgraph::license::RegisterLicenseSettings(memgraph::license::global_license_checker,
|
||||||
memgraph::utils::global_settings);
|
memgraph::utils::global_settings);
|
||||||
|
|
||||||
memgraph::utils::license::global_license_checker.CheckEnvLicense();
|
memgraph::license::global_license_checker.CheckEnvLicense();
|
||||||
if (!FLAGS_organization_name.empty() && !FLAGS_license_key.empty()) {
|
if (!FLAGS_organization_name.empty() && !FLAGS_license_key.empty()) {
|
||||||
memgraph::utils::license::global_license_checker.SetLicenseInfoOverride(FLAGS_license_key, FLAGS_organization_name);
|
memgraph::license::global_license_checker.SetLicenseInfoOverride(FLAGS_license_key, FLAGS_organization_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
memgraph::utils::license::global_license_checker.StartBackgroundLicenseChecker(memgraph::utils::global_settings);
|
memgraph::license::global_license_checker.StartBackgroundLicenseChecker(memgraph::utils::global_settings);
|
||||||
|
|
||||||
// All enterprise features should be constructed before the main database
|
// All enterprise features should be constructed before the main database
|
||||||
// storage. This will cause them to be destructed *after* the main database
|
// storage. This will cause them to be destructed *after* the main database
|
||||||
@ -906,12 +908,15 @@ int main(int argc, char **argv) {
|
|||||||
ServerT server(server_endpoint, &session_data, &context, FLAGS_bolt_session_inactivity_timeout, service_name,
|
ServerT server(server_endpoint, &session_data, &context, FLAGS_bolt_session_inactivity_timeout, service_name,
|
||||||
FLAGS_bolt_num_workers);
|
FLAGS_bolt_num_workers);
|
||||||
|
|
||||||
|
const auto run_id = memgraph::utils::GenerateUUID();
|
||||||
|
const auto machine_id = memgraph::utils::GetMachineId();
|
||||||
|
session_data.run_id = run_id;
|
||||||
|
|
||||||
// Setup telemetry
|
// Setup telemetry
|
||||||
|
static constexpr auto telemetry_server{"https://telemetry.memgraph.com/88b5e7e8-746a-11e8-9f85-538a9e9690cc/"};
|
||||||
std::optional<memgraph::telemetry::Telemetry> telemetry;
|
std::optional<memgraph::telemetry::Telemetry> telemetry;
|
||||||
if (FLAGS_telemetry_enabled) {
|
if (FLAGS_telemetry_enabled) {
|
||||||
telemetry.emplace("https://telemetry.memgraph.com/88b5e7e8-746a-11e8-9f85-538a9e9690cc/",
|
telemetry.emplace(telemetry_server, data_directory / "telemetry", run_id, machine_id, std::chrono::minutes(10));
|
||||||
data_directory / "telemetry", std::chrono::minutes(10));
|
|
||||||
session_data.run_id = telemetry->GetRunId();
|
|
||||||
telemetry->AddCollector("storage", [&db]() -> nlohmann::json {
|
telemetry->AddCollector("storage", [&db]() -> nlohmann::json {
|
||||||
auto info = db.GetInfo();
|
auto info = db.GetInfo();
|
||||||
return {{"vertices", info.vertex_count}, {"edges", info.edge_count}};
|
return {{"vertices", info.vertex_count}, {"edges", info.edge_count}};
|
||||||
@ -927,6 +932,8 @@ int main(int argc, char **argv) {
|
|||||||
return memgraph::query::plan::CallProcedure::GetAndResetCounters();
|
return memgraph::query::plan::CallProcedure::GetAndResetCounters();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
memgraph::license::LicenseInfoSender license_info_sender(telemetry_server, run_id, machine_id, memory_limit,
|
||||||
|
memgraph::license::global_license_checker.GetLicenseInfo());
|
||||||
|
|
||||||
memgraph::communication::websocket::SafeAuth websocket_auth{&auth};
|
memgraph::communication::websocket::SafeAuth websocket_auth{&auth};
|
||||||
memgraph::communication::websocket::Server websocket_server{
|
memgraph::communication::websocket::Server websocket_server{
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "auth/models.hpp"
|
#include "auth/models.hpp"
|
||||||
#include "glue/communication.hpp"
|
#include "glue/communication.hpp"
|
||||||
|
#include "license/license.hpp"
|
||||||
#include "memory/memory_control.hpp"
|
#include "memory/memory_control.hpp"
|
||||||
#include "query/constants.hpp"
|
#include "query/constants.hpp"
|
||||||
#include "query/context.hpp"
|
#include "query/context.hpp"
|
||||||
@ -54,7 +55,6 @@
|
|||||||
#include "utils/event_counter.hpp"
|
#include "utils/event_counter.hpp"
|
||||||
#include "utils/exceptions.hpp"
|
#include "utils/exceptions.hpp"
|
||||||
#include "utils/flag_validation.hpp"
|
#include "utils/flag_validation.hpp"
|
||||||
#include "utils/license.hpp"
|
|
||||||
#include "utils/likely.hpp"
|
#include "utils/likely.hpp"
|
||||||
#include "utils/logging.hpp"
|
#include "utils/logging.hpp"
|
||||||
#include "utils/memory.hpp"
|
#include "utils/memory.hpp"
|
||||||
@ -299,7 +299,7 @@ Callback HandleAuthQuery(AuthQuery *auth_query, AuthQueryHandler *auth, const Pa
|
|||||||
|
|
||||||
Callback callback;
|
Callback callback;
|
||||||
|
|
||||||
const auto license_check_result = utils::license::global_license_checker.IsValidLicense(utils::global_settings);
|
const auto license_check_result = license::global_license_checker.IsEnterpriseValid(utils::global_settings);
|
||||||
|
|
||||||
static const std::unordered_set enterprise_only_methods{
|
static const std::unordered_set enterprise_only_methods{
|
||||||
AuthQuery::Action::CREATE_ROLE, AuthQuery::Action::DROP_ROLE, AuthQuery::Action::SET_ROLE,
|
AuthQuery::Action::CREATE_ROLE, AuthQuery::Action::DROP_ROLE, AuthQuery::Action::SET_ROLE,
|
||||||
@ -309,7 +309,7 @@ Callback HandleAuthQuery(AuthQuery *auth_query, AuthQueryHandler *auth, const Pa
|
|||||||
|
|
||||||
if (license_check_result.HasError() && enterprise_only_methods.contains(auth_query->action_)) {
|
if (license_check_result.HasError() && enterprise_only_methods.contains(auth_query->action_)) {
|
||||||
throw utils::BasicException(
|
throw utils::BasicException(
|
||||||
utils::license::LicenseCheckErrorToString(license_check_result.GetError(), "advanced authentication features"));
|
license::LicenseCheckErrorToString(license_check_result.GetError(), "advanced authentication features"));
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (auth_query->action_) {
|
switch (auth_query->action_) {
|
||||||
@ -1017,7 +1017,7 @@ PullPlan::PullPlan(const std::shared_ptr<CachedPlan> plan, const Parameters &par
|
|||||||
ctx_.evaluation_context.properties = NamesToProperties(plan->ast_storage().properties_, dba);
|
ctx_.evaluation_context.properties = NamesToProperties(plan->ast_storage().properties_, dba);
|
||||||
ctx_.evaluation_context.labels = NamesToLabels(plan->ast_storage().labels_, dba);
|
ctx_.evaluation_context.labels = NamesToLabels(plan->ast_storage().labels_, dba);
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (utils::license::global_license_checker.IsValidLicenseFast() && username.has_value() && dba) {
|
if (license::global_license_checker.IsEnterpriseValidFast() && username.has_value() && dba) {
|
||||||
ctx_.auth_checker = interpreter_context->auth_checker->GetFineGrainedAuthChecker(*username, dba);
|
ctx_.auth_checker = interpreter_context->auth_checker->GetFineGrainedAuthChecker(*username, dba);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include <cppitertools/imap.hpp>
|
#include <cppitertools/imap.hpp>
|
||||||
#include "spdlog/spdlog.h"
|
#include "spdlog/spdlog.h"
|
||||||
|
|
||||||
|
#include "license/license.hpp"
|
||||||
#include "query/auth_checker.hpp"
|
#include "query/auth_checker.hpp"
|
||||||
#include "query/context.hpp"
|
#include "query/context.hpp"
|
||||||
#include "query/db_accessor.hpp"
|
#include "query/db_accessor.hpp"
|
||||||
@ -47,7 +48,6 @@
|
|||||||
#include "utils/event_counter.hpp"
|
#include "utils/event_counter.hpp"
|
||||||
#include "utils/exceptions.hpp"
|
#include "utils/exceptions.hpp"
|
||||||
#include "utils/fnv.hpp"
|
#include "utils/fnv.hpp"
|
||||||
#include "utils/license.hpp"
|
|
||||||
#include "utils/likely.hpp"
|
#include "utils/likely.hpp"
|
||||||
#include "utils/logging.hpp"
|
#include "utils/logging.hpp"
|
||||||
#include "utils/memory.hpp"
|
#include "utils/memory.hpp"
|
||||||
@ -242,7 +242,7 @@ CreateNode::CreateNodeCursor::CreateNodeCursor(const CreateNode &self, utils::Me
|
|||||||
bool CreateNode::CreateNodeCursor::Pull(Frame &frame, ExecutionContext &context) {
|
bool CreateNode::CreateNodeCursor::Pull(Frame &frame, ExecutionContext &context) {
|
||||||
SCOPED_PROFILE_OP("CreateNode");
|
SCOPED_PROFILE_OP("CreateNode");
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||||
!context.auth_checker->Has(self_.node_info_.labels,
|
!context.auth_checker->Has(self_.node_info_.labels,
|
||||||
memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
|
memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
|
||||||
throw QueryRuntimeException("Vertex not created due to not having enough permission!");
|
throw QueryRuntimeException("Vertex not created due to not having enough permission!");
|
||||||
@ -334,7 +334,7 @@ bool CreateExpand::CreateExpandCursor::Pull(Frame &frame, ExecutionContext &cont
|
|||||||
if (!input_cursor_->Pull(frame, context)) return false;
|
if (!input_cursor_->Pull(frame, context)) return false;
|
||||||
|
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
const auto fine_grained_permission = self_.existing_node_
|
const auto fine_grained_permission = self_.existing_node_
|
||||||
? memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE
|
? memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE
|
||||||
|
|
||||||
@ -433,8 +433,7 @@ class ScanAllCursor : public Cursor {
|
|||||||
vertices_it_.emplace(vertices_.value().begin());
|
vertices_it_.emplace(vertices_.value().begin());
|
||||||
}
|
}
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker && !FindNextVertex(context)) {
|
||||||
!FindNextVertex(context)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -731,7 +730,7 @@ bool Expand::ExpandCursor::Pull(Frame &frame, ExecutionContext &context) {
|
|||||||
if (in_edges_ && *in_edges_it_ != in_edges_->end()) {
|
if (in_edges_ && *in_edges_it_ != in_edges_->end()) {
|
||||||
auto edge = *(*in_edges_it_)++;
|
auto edge = *(*in_edges_it_)++;
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||||
!(context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
!(context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
||||||
context.auth_checker->Has(edge.From(), self_.view_,
|
context.auth_checker->Has(edge.From(), self_.view_,
|
||||||
memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
||||||
@ -752,7 +751,7 @@ bool Expand::ExpandCursor::Pull(Frame &frame, ExecutionContext &context) {
|
|||||||
// already done in the block above
|
// already done in the block above
|
||||||
if (self_.common_.direction == EdgeAtom::Direction::BOTH && edge.IsCycle()) continue;
|
if (self_.common_.direction == EdgeAtom::Direction::BOTH && edge.IsCycle()) continue;
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||||
!(context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
!(context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
||||||
context.auth_checker->Has(edge.To(), self_.view_,
|
context.auth_checker->Has(edge.To(), self_.view_,
|
||||||
memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
||||||
@ -1089,7 +1088,7 @@ class ExpandVariableCursor : public Cursor {
|
|||||||
VertexAccessor current_vertex =
|
VertexAccessor current_vertex =
|
||||||
current_edge.second == EdgeAtom::Direction::IN ? current_edge.first.From() : current_edge.first.To();
|
current_edge.second == EdgeAtom::Direction::IN ? current_edge.first.From() : current_edge.first.To();
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||||
!(context.auth_checker->Has(current_edge.first, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
!(context.auth_checker->Has(current_edge.first, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
||||||
context.auth_checker->Has(current_vertex, storage::View::OLD,
|
context.auth_checker->Has(current_vertex, storage::View::OLD,
|
||||||
memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
||||||
@ -1258,7 +1257,7 @@ class STShortestPathCursor : public query::plan::Cursor {
|
|||||||
auto out_edges = UnwrapEdgesResult(vertex.OutEdges(storage::View::OLD, self_.common_.edge_types));
|
auto out_edges = UnwrapEdgesResult(vertex.OutEdges(storage::View::OLD, self_.common_.edge_types));
|
||||||
for (const auto &edge : out_edges) {
|
for (const auto &edge : out_edges) {
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||||
!(context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
!(context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
||||||
context.auth_checker->Has(edge.To(), storage::View::OLD,
|
context.auth_checker->Has(edge.To(), storage::View::OLD,
|
||||||
memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
||||||
@ -1284,7 +1283,7 @@ class STShortestPathCursor : public query::plan::Cursor {
|
|||||||
auto in_edges = UnwrapEdgesResult(vertex.InEdges(storage::View::OLD, self_.common_.edge_types));
|
auto in_edges = UnwrapEdgesResult(vertex.InEdges(storage::View::OLD, self_.common_.edge_types));
|
||||||
for (const auto &edge : in_edges) {
|
for (const auto &edge : in_edges) {
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||||
!(context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
!(context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
||||||
context.auth_checker->Has(edge.From(), storage::View::OLD,
|
context.auth_checker->Has(edge.From(), storage::View::OLD,
|
||||||
memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
||||||
@ -1324,7 +1323,7 @@ class STShortestPathCursor : public query::plan::Cursor {
|
|||||||
auto out_edges = UnwrapEdgesResult(vertex.OutEdges(storage::View::OLD, self_.common_.edge_types));
|
auto out_edges = UnwrapEdgesResult(vertex.OutEdges(storage::View::OLD, self_.common_.edge_types));
|
||||||
for (const auto &edge : out_edges) {
|
for (const auto &edge : out_edges) {
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||||
!(context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
!(context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
||||||
context.auth_checker->Has(edge.To(), storage::View::OLD,
|
context.auth_checker->Has(edge.To(), storage::View::OLD,
|
||||||
memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
||||||
@ -1349,7 +1348,7 @@ class STShortestPathCursor : public query::plan::Cursor {
|
|||||||
auto in_edges = UnwrapEdgesResult(vertex.InEdges(storage::View::OLD, self_.common_.edge_types));
|
auto in_edges = UnwrapEdgesResult(vertex.InEdges(storage::View::OLD, self_.common_.edge_types));
|
||||||
for (const auto &edge : in_edges) {
|
for (const auto &edge : in_edges) {
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||||
!(context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
!(context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
||||||
context.auth_checker->Has(edge.From(), storage::View::OLD,
|
context.auth_checker->Has(edge.From(), storage::View::OLD,
|
||||||
memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
||||||
@ -1406,7 +1405,7 @@ class SingleSourceShortestPathCursor : public query::plan::Cursor {
|
|||||||
// if we already processed the given vertex it doesn't get expanded
|
// if we already processed the given vertex it doesn't get expanded
|
||||||
if (processed_.find(vertex) != processed_.end()) return;
|
if (processed_.find(vertex) != processed_.end()) return;
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||||
!(context.auth_checker->Has(vertex, storage::View::OLD,
|
!(context.auth_checker->Has(vertex, storage::View::OLD,
|
||||||
memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
||||||
context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
||||||
@ -1592,7 +1591,7 @@ class ExpandWeightedShortestPathCursor : public query::plan::Cursor {
|
|||||||
int64_t depth) {
|
int64_t depth) {
|
||||||
auto *memory = evaluator.GetMemoryResource();
|
auto *memory = evaluator.GetMemoryResource();
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||||
!(context.auth_checker->Has(vertex, storage::View::OLD,
|
!(context.auth_checker->Has(vertex, storage::View::OLD,
|
||||||
memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
||||||
context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
||||||
@ -1902,7 +1901,7 @@ class ExpandAllShortestPathsCursor : public query::plan::Cursor {
|
|||||||
auto out_edges = UnwrapEdgesResult(vertex.OutEdges(storage::View::OLD, self_.common_.edge_types));
|
auto out_edges = UnwrapEdgesResult(vertex.OutEdges(storage::View::OLD, self_.common_.edge_types));
|
||||||
for (const auto &edge : out_edges) {
|
for (const auto &edge : out_edges) {
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||||
!(context.auth_checker->Has(edge.To(), storage::View::OLD,
|
!(context.auth_checker->Has(edge.To(), storage::View::OLD,
|
||||||
memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
||||||
context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
||||||
@ -1916,7 +1915,7 @@ class ExpandAllShortestPathsCursor : public query::plan::Cursor {
|
|||||||
auto in_edges = UnwrapEdgesResult(vertex.InEdges(storage::View::OLD, self_.common_.edge_types));
|
auto in_edges = UnwrapEdgesResult(vertex.InEdges(storage::View::OLD, self_.common_.edge_types));
|
||||||
for (const auto &edge : in_edges) {
|
for (const auto &edge : in_edges) {
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||||
!(context.auth_checker->Has(edge.From(), storage::View::OLD,
|
!(context.auth_checker->Has(edge.From(), storage::View::OLD,
|
||||||
memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
memgraph::query::AuthQuery::FineGrainedPrivilege::READ) &&
|
||||||
context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) {
|
||||||
@ -1973,7 +1972,6 @@ class ExpandAllShortestPathsCursor : public query::plan::Cursor {
|
|||||||
edges_on_frame.emplace(edges_on_frame.begin(), current_edge);
|
edges_on_frame.emplace(edges_on_frame.begin(), current_edge);
|
||||||
|
|
||||||
auto next_vertex = current_edge_direction == EdgeAtom::Direction::IN ? current_edge.From() : current_edge.To();
|
auto next_vertex = current_edge_direction == EdgeAtom::Direction::IN ? current_edge.From() : current_edge.To();
|
||||||
frame[self_.common_.node_symbol] = next_vertex;
|
|
||||||
frame[self_.total_weight_.value()] = current_weight;
|
frame[self_.total_weight_.value()] = current_weight;
|
||||||
|
|
||||||
if (next_edges_.find({next_vertex, traversal_stack_.size()}) != next_edges_.end()) {
|
if (next_edges_.find({next_vertex, traversal_stack_.size()}) != next_edges_.end()) {
|
||||||
@ -1986,6 +1984,15 @@ class ExpandAllShortestPathsCursor : public query::plan::Cursor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((current_weight > visited_cost_.at(next_vertex)).ValueBool()) continue;
|
if ((current_weight > visited_cost_.at(next_vertex)).ValueBool()) continue;
|
||||||
|
|
||||||
|
// Place destination node on the frame, handle existence flag
|
||||||
|
if (self_.common_.existing_node) {
|
||||||
|
const auto &node = frame[self_.common_.node_symbol];
|
||||||
|
ExpectType(self_.common_.node_symbol, node, TypedValue::Type::Vertex);
|
||||||
|
if (node.ValueVertex() != next_vertex) continue;
|
||||||
|
} else {
|
||||||
|
frame[self_.common_.node_symbol] = next_vertex;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2366,7 +2373,7 @@ bool Delete::DeleteCursor::Pull(Frame &frame, ExecutionContext &context) {
|
|||||||
if (expression_result.type() == TypedValue::Type::Edge) {
|
if (expression_result.type() == TypedValue::Type::Edge) {
|
||||||
auto &ea = expression_result.ValueEdge();
|
auto &ea = expression_result.ValueEdge();
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||||
!(context.auth_checker->Has(ea, query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE) &&
|
!(context.auth_checker->Has(ea, query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE) &&
|
||||||
context.auth_checker->Has(ea.To(), storage::View::NEW, query::AuthQuery::FineGrainedPrivilege::UPDATE) &&
|
context.auth_checker->Has(ea.To(), storage::View::NEW, query::AuthQuery::FineGrainedPrivilege::UPDATE) &&
|
||||||
context.auth_checker->Has(ea.From(), storage::View::NEW, query::AuthQuery::FineGrainedPrivilege::UPDATE))) {
|
context.auth_checker->Has(ea.From(), storage::View::NEW, query::AuthQuery::FineGrainedPrivilege::UPDATE))) {
|
||||||
@ -2399,7 +2406,7 @@ bool Delete::DeleteCursor::Pull(Frame &frame, ExecutionContext &context) {
|
|||||||
case TypedValue::Type::Vertex: {
|
case TypedValue::Type::Vertex: {
|
||||||
auto &va = expression_result.ValueVertex();
|
auto &va = expression_result.ValueVertex();
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||||
!context.auth_checker->Has(va, storage::View::NEW, query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
|
!context.auth_checker->Has(va, storage::View::NEW, query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
|
||||||
throw QueryRuntimeException("Vertex not deleted due to not having enough permission!");
|
throw QueryRuntimeException("Vertex not deleted due to not having enough permission!");
|
||||||
}
|
}
|
||||||
@ -2508,7 +2515,7 @@ bool SetProperty::SetPropertyCursor::Pull(Frame &frame, ExecutionContext &contex
|
|||||||
switch (lhs.type()) {
|
switch (lhs.type()) {
|
||||||
case TypedValue::Type::Vertex: {
|
case TypedValue::Type::Vertex: {
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||||
!context.auth_checker->Has(lhs.ValueVertex(), storage::View::NEW,
|
!context.auth_checker->Has(lhs.ValueVertex(), storage::View::NEW,
|
||||||
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
||||||
throw QueryRuntimeException("Vertex property not set due to not having enough permission!");
|
throw QueryRuntimeException("Vertex property not set due to not having enough permission!");
|
||||||
@ -2525,7 +2532,7 @@ bool SetProperty::SetPropertyCursor::Pull(Frame &frame, ExecutionContext &contex
|
|||||||
}
|
}
|
||||||
case TypedValue::Type::Edge: {
|
case TypedValue::Type::Edge: {
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||||
!context.auth_checker->Has(lhs.ValueEdge(), memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
!context.auth_checker->Has(lhs.ValueEdge(), memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
||||||
throw QueryRuntimeException("Edge property not set due to not having enough permission!");
|
throw QueryRuntimeException("Edge property not set due to not having enough permission!");
|
||||||
}
|
}
|
||||||
@ -2724,7 +2731,7 @@ bool SetProperties::SetPropertiesCursor::Pull(Frame &frame, ExecutionContext &co
|
|||||||
switch (lhs.type()) {
|
switch (lhs.type()) {
|
||||||
case TypedValue::Type::Vertex:
|
case TypedValue::Type::Vertex:
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||||
!context.auth_checker->Has(lhs.ValueVertex(), storage::View::NEW,
|
!context.auth_checker->Has(lhs.ValueVertex(), storage::View::NEW,
|
||||||
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
||||||
throw QueryRuntimeException("Vertex properties not set due to not having enough permission!");
|
throw QueryRuntimeException("Vertex properties not set due to not having enough permission!");
|
||||||
@ -2735,7 +2742,7 @@ bool SetProperties::SetPropertiesCursor::Pull(Frame &frame, ExecutionContext &co
|
|||||||
break;
|
break;
|
||||||
case TypedValue::Type::Edge:
|
case TypedValue::Type::Edge:
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||||
!context.auth_checker->Has(lhs.ValueEdge(), memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
!context.auth_checker->Has(lhs.ValueEdge(), memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
||||||
throw QueryRuntimeException("Edge properties not set due to not having enough permission!");
|
throw QueryRuntimeException("Edge properties not set due to not having enough permission!");
|
||||||
}
|
}
|
||||||
@ -2778,7 +2785,7 @@ bool SetLabels::SetLabelsCursor::Pull(Frame &frame, ExecutionContext &context) {
|
|||||||
SCOPED_PROFILE_OP("SetLabels");
|
SCOPED_PROFILE_OP("SetLabels");
|
||||||
|
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||||
!context.auth_checker->Has(self_.labels_, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
|
!context.auth_checker->Has(self_.labels_, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
|
||||||
throw QueryRuntimeException("Couldn't set label due to not having enough permission!");
|
throw QueryRuntimeException("Couldn't set label due to not having enough permission!");
|
||||||
}
|
}
|
||||||
@ -2793,7 +2800,7 @@ bool SetLabels::SetLabelsCursor::Pull(Frame &frame, ExecutionContext &context) {
|
|||||||
auto &vertex = vertex_value.ValueVertex();
|
auto &vertex = vertex_value.ValueVertex();
|
||||||
|
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||||
!context.auth_checker->Has(vertex, storage::View::OLD,
|
!context.auth_checker->Has(vertex, storage::View::OLD,
|
||||||
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
||||||
throw QueryRuntimeException("Couldn't set label due to not having enough permission!");
|
throw QueryRuntimeException("Couldn't set label due to not having enough permission!");
|
||||||
@ -2883,7 +2890,7 @@ bool RemoveProperty::RemovePropertyCursor::Pull(Frame &frame, ExecutionContext &
|
|||||||
switch (lhs.type()) {
|
switch (lhs.type()) {
|
||||||
case TypedValue::Type::Vertex:
|
case TypedValue::Type::Vertex:
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||||
!context.auth_checker->Has(lhs.ValueVertex(), storage::View::NEW,
|
!context.auth_checker->Has(lhs.ValueVertex(), storage::View::NEW,
|
||||||
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
||||||
throw QueryRuntimeException("Vertex property not removed due to not having enough permission!");
|
throw QueryRuntimeException("Vertex property not removed due to not having enough permission!");
|
||||||
@ -2893,7 +2900,7 @@ bool RemoveProperty::RemovePropertyCursor::Pull(Frame &frame, ExecutionContext &
|
|||||||
break;
|
break;
|
||||||
case TypedValue::Type::Edge:
|
case TypedValue::Type::Edge:
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||||
!context.auth_checker->Has(lhs.ValueEdge(), memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
!context.auth_checker->Has(lhs.ValueEdge(), memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
||||||
throw QueryRuntimeException("Edge property not removed due to not having enough permission!");
|
throw QueryRuntimeException("Edge property not removed due to not having enough permission!");
|
||||||
}
|
}
|
||||||
@ -2936,7 +2943,7 @@ bool RemoveLabels::RemoveLabelsCursor::Pull(Frame &frame, ExecutionContext &cont
|
|||||||
SCOPED_PROFILE_OP("RemoveLabels");
|
SCOPED_PROFILE_OP("RemoveLabels");
|
||||||
|
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||||
!context.auth_checker->Has(self_.labels_, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
|
!context.auth_checker->Has(self_.labels_, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
|
||||||
throw QueryRuntimeException("Couldn't remove label due to not having enough permission!");
|
throw QueryRuntimeException("Couldn't remove label due to not having enough permission!");
|
||||||
}
|
}
|
||||||
@ -2951,7 +2958,7 @@ bool RemoveLabels::RemoveLabelsCursor::Pull(Frame &frame, ExecutionContext &cont
|
|||||||
auto &vertex = vertex_value.ValueVertex();
|
auto &vertex = vertex_value.ValueVertex();
|
||||||
|
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker &&
|
if (license::global_license_checker.IsEnterpriseValidFast() && context.auth_checker &&
|
||||||
!context.auth_checker->Has(vertex, storage::View::OLD,
|
!context.auth_checker->Has(vertex, storage::View::OLD,
|
||||||
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
||||||
throw QueryRuntimeException("Couldn't remove label due to not having enough permission!");
|
throw QueryRuntimeException("Couldn't remove label due to not having enough permission!");
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include "license/license.hpp"
|
||||||
#include "mg_procedure.h"
|
#include "mg_procedure.h"
|
||||||
#include "module.hpp"
|
#include "module.hpp"
|
||||||
#include "query/frontend/ast/ast.hpp"
|
#include "query/frontend/ast/ast.hpp"
|
||||||
@ -32,7 +33,6 @@
|
|||||||
#include "storage/v2/view.hpp"
|
#include "storage/v2/view.hpp"
|
||||||
#include "utils/algorithm.hpp"
|
#include "utils/algorithm.hpp"
|
||||||
#include "utils/concepts.hpp"
|
#include "utils/concepts.hpp"
|
||||||
#include "utils/license.hpp"
|
|
||||||
#include "utils/logging.hpp"
|
#include "utils/logging.hpp"
|
||||||
#include "utils/math.hpp"
|
#include "utils/math.hpp"
|
||||||
#include "utils/memory.hpp"
|
#include "utils/memory.hpp"
|
||||||
@ -1653,7 +1653,7 @@ mgp_error mgp_vertex_set_property(struct mgp_vertex *v, const char *property_nam
|
|||||||
auto *ctx = v->graph->ctx;
|
auto *ctx = v->graph->ctx;
|
||||||
|
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast() && ctx && ctx->auth_checker &&
|
if (memgraph::license::global_license_checker.IsEnterpriseValidFast() && ctx && ctx->auth_checker &&
|
||||||
!ctx->auth_checker->Has(v->getImpl(), v->graph->view,
|
!ctx->auth_checker->Has(v->getImpl(), v->graph->view,
|
||||||
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
||||||
throw AuthorizationException{"Insufficient permissions for setting a property on vertex!"};
|
throw AuthorizationException{"Insufficient permissions for setting a property on vertex!"};
|
||||||
@ -1706,7 +1706,7 @@ mgp_error mgp_vertex_add_label(struct mgp_vertex *v, mgp_label label) {
|
|||||||
const auto label_id = std::visit([label](auto *impl) { return impl->NameToLabel(label.name); }, v->graph->impl);
|
const auto label_id = std::visit([label](auto *impl) { return impl->NameToLabel(label.name); }, v->graph->impl);
|
||||||
|
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast() && ctx && ctx->auth_checker &&
|
if (memgraph::license::global_license_checker.IsEnterpriseValidFast() && ctx && ctx->auth_checker &&
|
||||||
!(ctx->auth_checker->Has(v->getImpl(), v->graph->view,
|
!(ctx->auth_checker->Has(v->getImpl(), v->graph->view,
|
||||||
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE) &&
|
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE) &&
|
||||||
ctx->auth_checker->Has({label_id}, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE))) {
|
ctx->auth_checker->Has({label_id}, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE))) {
|
||||||
@ -1750,7 +1750,7 @@ mgp_error mgp_vertex_remove_label(struct mgp_vertex *v, mgp_label label) {
|
|||||||
const auto label_id = std::visit([&label](auto *impl) { return impl->NameToLabel(label.name); }, v->graph->impl);
|
const auto label_id = std::visit([&label](auto *impl) { return impl->NameToLabel(label.name); }, v->graph->impl);
|
||||||
|
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast() && ctx && ctx->auth_checker &&
|
if (memgraph::license::global_license_checker.IsEnterpriseValidFast() && ctx && ctx->auth_checker &&
|
||||||
!(ctx->auth_checker->Has(v->getImpl(), v->graph->view,
|
!(ctx->auth_checker->Has(v->getImpl(), v->graph->view,
|
||||||
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE) &&
|
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE) &&
|
||||||
ctx->auth_checker->Has({label_id}, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE))) {
|
ctx->auth_checker->Has({label_id}, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE))) {
|
||||||
@ -1989,7 +1989,7 @@ mgp_error mgp_vertex_iter_in_edges(mgp_vertex *v, mgp_memory *memory, mgp_edges_
|
|||||||
it->in.emplace(std::move(*maybe_edges));
|
it->in.emplace(std::move(*maybe_edges));
|
||||||
it->in_it.emplace(it->in->begin());
|
it->in_it.emplace(it->in->begin());
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
NextPermittedEdge(*it, true);
|
NextPermittedEdge(*it, true);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -2041,7 +2041,7 @@ mgp_error mgp_vertex_iter_out_edges(mgp_vertex *v, mgp_memory *memory, mgp_edges
|
|||||||
it->out_it.emplace(it->out->begin());
|
it->out_it.emplace(it->out->begin());
|
||||||
|
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
NextPermittedEdge(*it, false);
|
NextPermittedEdge(*it, false);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -2099,7 +2099,7 @@ mgp_error mgp_edges_iterator_next(mgp_edges_iterator *it, mgp_edge **result) {
|
|||||||
++*impl_it;
|
++*impl_it;
|
||||||
|
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
NextPermittedEdge(*it, for_in);
|
NextPermittedEdge(*it, for_in);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -2124,10 +2124,7 @@ mgp_error mgp_edges_iterator_next(mgp_edges_iterator *it, mgp_edge **result) {
|
|||||||
return &*it->current_e;
|
return &*it->current_e;
|
||||||
};
|
};
|
||||||
if (it->in_it) {
|
if (it->in_it) {
|
||||||
auto *result = next(true);
|
return next(true);
|
||||||
if (result != nullptr) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return next(false);
|
return next(false);
|
||||||
},
|
},
|
||||||
@ -2205,7 +2202,7 @@ mgp_error mgp_edge_set_property(struct mgp_edge *e, const char *property_name, m
|
|||||||
auto *ctx = e->from.graph->ctx;
|
auto *ctx = e->from.graph->ctx;
|
||||||
|
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast() && ctx && ctx->auth_checker &&
|
if (memgraph::license::global_license_checker.IsEnterpriseValidFast() && ctx && ctx->auth_checker &&
|
||||||
!ctx->auth_checker->Has(e->impl, memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
!ctx->auth_checker->Has(e->impl, memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
||||||
throw AuthorizationException{"Insufficient permissions for setting a property on edge!"};
|
throw AuthorizationException{"Insufficient permissions for setting a property on edge!"};
|
||||||
}
|
}
|
||||||
@ -2313,7 +2310,7 @@ mgp_error mgp_graph_create_vertex(struct mgp_graph *graph, mgp_memory *memory, m
|
|||||||
[=]() -> mgp_vertex * {
|
[=]() -> mgp_vertex * {
|
||||||
|
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast() && graph->ctx &&
|
if (memgraph::license::global_license_checker.IsEnterpriseValidFast() && graph->ctx &&
|
||||||
graph->ctx->auth_checker &&
|
graph->ctx->auth_checker &&
|
||||||
!graph->ctx->auth_checker->HasGlobalPrivilegeOnVertices(
|
!graph->ctx->auth_checker->HasGlobalPrivilegeOnVertices(
|
||||||
memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
|
memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
|
||||||
@ -2343,7 +2340,7 @@ mgp_error mgp_graph_delete_vertex(struct mgp_graph *graph, mgp_vertex *vertex) {
|
|||||||
auto *ctx = graph->ctx;
|
auto *ctx = graph->ctx;
|
||||||
|
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast() && ctx && ctx->auth_checker &&
|
if (memgraph::license::global_license_checker.IsEnterpriseValidFast() && ctx && ctx->auth_checker &&
|
||||||
!ctx->auth_checker->Has(vertex->getImpl(), graph->view,
|
!ctx->auth_checker->Has(vertex->getImpl(), graph->view,
|
||||||
memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
|
memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
|
||||||
throw AuthorizationException{"Insufficient permissions for deleting a vertex!"};
|
throw AuthorizationException{"Insufficient permissions for deleting a vertex!"};
|
||||||
@ -2394,7 +2391,7 @@ mgp_error mgp_graph_detach_delete_vertex(struct mgp_graph *graph, mgp_vertex *ve
|
|||||||
return WrapExceptions([=] {
|
return WrapExceptions([=] {
|
||||||
auto *ctx = graph->ctx;
|
auto *ctx = graph->ctx;
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast() && ctx && ctx->auth_checker &&
|
if (memgraph::license::global_license_checker.IsEnterpriseValidFast() && ctx && ctx->auth_checker &&
|
||||||
!ctx->auth_checker->Has(vertex->getImpl(), graph->view,
|
!ctx->auth_checker->Has(vertex->getImpl(), graph->view,
|
||||||
memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
|
memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
|
||||||
throw AuthorizationException{"Insufficient permissions for deleting a vertex!"};
|
throw AuthorizationException{"Insufficient permissions for deleting a vertex!"};
|
||||||
@ -2458,7 +2455,7 @@ mgp_error mgp_graph_create_edge(mgp_graph *graph, mgp_vertex *from, mgp_vertex *
|
|||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
const auto edge_id =
|
const auto edge_id =
|
||||||
std::visit([type](auto *impl) { return impl->NameToEdgeType(type.name); }, from->graph->impl);
|
std::visit([type](auto *impl) { return impl->NameToEdgeType(type.name); }, from->graph->impl);
|
||||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast() && ctx && ctx->auth_checker &&
|
if (memgraph::license::global_license_checker.IsEnterpriseValidFast() && ctx && ctx->auth_checker &&
|
||||||
!ctx->auth_checker->Has(edge_id, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
|
!ctx->auth_checker->Has(edge_id, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
|
||||||
throw AuthorizationException{"Insufficient permissions for creating edges!"};
|
throw AuthorizationException{"Insufficient permissions for creating edges!"};
|
||||||
}
|
}
|
||||||
@ -2519,7 +2516,7 @@ mgp_error mgp_graph_delete_edge(struct mgp_graph *graph, mgp_edge *edge) {
|
|||||||
return WrapExceptions([=] {
|
return WrapExceptions([=] {
|
||||||
auto *ctx = graph->ctx;
|
auto *ctx = graph->ctx;
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast() && ctx && ctx->auth_checker &&
|
if (memgraph::license::global_license_checker.IsEnterpriseValidFast() && ctx && ctx->auth_checker &&
|
||||||
!ctx->auth_checker->Has(edge->impl, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
|
!ctx->auth_checker->Has(edge->impl, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
|
||||||
throw AuthorizationException{"Insufficient permissions for deleting an edge!"};
|
throw AuthorizationException{"Insufficient permissions for deleting an edge!"};
|
||||||
}
|
}
|
||||||
@ -2581,7 +2578,7 @@ mgp_vertices_iterator::mgp_vertices_iterator(mgp_graph *graph, memgraph::utils::
|
|||||||
vertices(std::visit([graph](auto *impl) { return impl->Vertices(graph->view); }, graph->impl)),
|
vertices(std::visit([graph](auto *impl) { return impl->Vertices(graph->view); }, graph->impl)),
|
||||||
current_it(vertices.begin()) {
|
current_it(vertices.begin()) {
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
NextPermitted(*this);
|
NextPermitted(*this);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -2630,7 +2627,7 @@ mgp_error mgp_vertices_iterator_next(mgp_vertices_iterator *it, mgp_vertex **res
|
|||||||
|
|
||||||
++it->current_it;
|
++it->current_it;
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) {
|
if (memgraph::license::global_license_checker.IsEnterpriseValidFast()) {
|
||||||
NextPermitted(*it);
|
NextPermitted(*it);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
set(telemetry_src_files
|
set(telemetry_src_files
|
||||||
collectors.cpp
|
collectors.cpp
|
||||||
telemetry.cpp
|
telemetry.cpp)
|
||||||
system_info.cpp)
|
|
||||||
|
|
||||||
add_library(telemetry_lib STATIC ${telemetry_src_files})
|
add_library(mg-telemetry STATIC ${telemetry_src_files})
|
||||||
target_link_libraries(telemetry_lib mg-requests mg-kvstore mg-utils)
|
target_link_libraries(mg-telemetry mg-requests mg-kvstore mg-utils)
|
||||||
option(MG_TELEMETRY_ID_OVERRIDE "Override for the telemetry ID" STRING)
|
option(MG_TELEMETRY_ID_OVERRIDE "Override for the telemetry ID" STRING)
|
||||||
if (MG_TELEMETRY_ID_OVERRIDE)
|
|
||||||
|
if(MG_TELEMETRY_ID_OVERRIDE)
|
||||||
message(WARNING "Using telemetry ID override: ${MG_TELEMETRY_ID_OVERRIDE}")
|
message(WARNING "Using telemetry ID override: ${MG_TELEMETRY_ID_OVERRIDE}")
|
||||||
target_compile_definitions(telemetry_lib PRIVATE MG_TELEMETRY_ID_OVERRIDE="${MG_TELEMETRY_ID_OVERRIDE}")
|
target_compile_definitions(mg-telemetry PRIVATE MG_TELEMETRY_ID_OVERRIDE="${MG_TELEMETRY_ID_OVERRIDE}")
|
||||||
endif()
|
endif()
|
||||||
|
@ -17,38 +17,24 @@
|
|||||||
|
|
||||||
#include "requests/requests.hpp"
|
#include "requests/requests.hpp"
|
||||||
#include "telemetry/collectors.hpp"
|
#include "telemetry/collectors.hpp"
|
||||||
#include "telemetry/system_info.hpp"
|
|
||||||
#include "utils/file.hpp"
|
#include "utils/file.hpp"
|
||||||
#include "utils/logging.hpp"
|
#include "utils/logging.hpp"
|
||||||
|
#include "utils/system_info.hpp"
|
||||||
#include "utils/timestamp.hpp"
|
#include "utils/timestamp.hpp"
|
||||||
#include "utils/uuid.hpp"
|
#include "utils/uuid.hpp"
|
||||||
|
|
||||||
namespace memgraph::telemetry {
|
namespace memgraph::telemetry {
|
||||||
namespace {
|
|
||||||
std::string GetMachineId() {
|
|
||||||
#ifdef MG_TELEMETRY_ID_OVERRIDE
|
|
||||||
return MG_TELEMETRY_ID_OVERRIDE;
|
|
||||||
#else
|
|
||||||
// We assume we're on linux and we need to read the machine id from /etc/machine-id
|
|
||||||
const auto machine_id_lines = utils::ReadLines("/etc/machine-id");
|
|
||||||
if (machine_id_lines.size() != 1) {
|
|
||||||
return "UNKNOWN";
|
|
||||||
}
|
|
||||||
return machine_id_lines[0];
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
const int kMaxBatchSize = 100;
|
constexpr auto kMaxBatchSize{100};
|
||||||
|
|
||||||
Telemetry::Telemetry(std::string url, std::filesystem::path storage_directory,
|
Telemetry::Telemetry(std::string url, std::filesystem::path storage_directory, std::string uuid, std::string machine_id,
|
||||||
std::chrono::duration<int64_t> refresh_interval, const uint64_t send_every_n)
|
std::chrono::duration<int64_t> refresh_interval, const uint64_t send_every_n)
|
||||||
: url_(std::move(url)),
|
: url_(std::move(url)),
|
||||||
uuid_(utils::GenerateUUID()),
|
uuid_(uuid),
|
||||||
machine_id_(GetMachineId()),
|
machine_id_(machine_id),
|
||||||
send_every_n_(send_every_n),
|
send_every_n_(send_every_n),
|
||||||
storage_(std::move(storage_directory)) {
|
storage_(std::move(storage_directory)) {
|
||||||
StoreData("startup", GetSystemInfo());
|
StoreData("startup", utils::GetSystemInfo());
|
||||||
AddCollector("resources", GetResourceUsage);
|
AddCollector("resources", GetResourceUsage);
|
||||||
AddCollector("uptime", [&]() -> nlohmann::json { return GetUptime(); });
|
AddCollector("uptime", [&]() -> nlohmann::json { return GetUptime(); });
|
||||||
scheduler_.Run("Telemetry", refresh_interval, [&] { CollectData(); });
|
scheduler_.Run("Telemetry", refresh_interval, [&] { CollectData(); });
|
||||||
@ -59,19 +45,15 @@ void Telemetry::AddCollector(const std::string &name, const std::function<const
|
|||||||
collectors_.emplace_back(name, func);
|
collectors_.emplace_back(name, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Telemetry::GetRunId() const { return uuid_; }
|
|
||||||
|
|
||||||
Telemetry::~Telemetry() {
|
Telemetry::~Telemetry() {
|
||||||
scheduler_.Stop();
|
scheduler_.Stop();
|
||||||
CollectData("shutdown");
|
CollectData("shutdown");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Telemetry::StoreData(const nlohmann::json &event, const nlohmann::json &data) {
|
void Telemetry::StoreData(const nlohmann::json &event, const nlohmann::json &data) {
|
||||||
nlohmann::json payload = {{"run_id", uuid_},
|
nlohmann::json payload = {
|
||||||
{"machine_id", machine_id_},
|
{"run_id", uuid_}, {"type", "telemetry"}, {"machine_id", machine_id_},
|
||||||
{"event", event},
|
{"event", event}, {"data", data}, {"timestamp", utils::Timestamp::Now().SecWithNsecSinceTheEpoch()}};
|
||||||
{"data", data},
|
|
||||||
{"timestamp", utils::Timestamp::Now().SecWithNsecSinceTheEpoch()}};
|
|
||||||
storage_.Put(fmt::format("{}:{}", uuid_, event.dump()), payload.dump());
|
storage_.Put(fmt::format("{}:{}", uuid_, event.dump()), payload.dump());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ namespace memgraph::telemetry {
|
|||||||
* This class implements the telemetry collector service. It periodically scapes
|
* This class implements the telemetry collector service. It periodically scapes
|
||||||
* all registered collectors and stores their data. With periodically scraping
|
* all registered collectors and stores their data. With periodically scraping
|
||||||
* the collectors the service collects machine information in the constructor
|
* the collectors the service collects machine information in the constructor
|
||||||
* and stores it. Also, it calles all collectors once more in the destructor so
|
* and stores it. Also, it calls all collectors once more in the destructor so
|
||||||
* that final stats can be collected. All data is stored persistently. If there
|
* that final stats can be collected. All data is stored persistently. If there
|
||||||
* is no internet connection the data will be sent when the internet connection
|
* is no internet connection the data will be sent when the internet connection
|
||||||
* is reestablished. If there is an issue with the internet connection that
|
* is reestablished. If there is an issue with the internet connection that
|
||||||
@ -34,14 +34,11 @@ namespace memgraph::telemetry {
|
|||||||
*/
|
*/
|
||||||
class Telemetry final {
|
class Telemetry final {
|
||||||
public:
|
public:
|
||||||
Telemetry(std::string url, std::filesystem::path storage_directory,
|
Telemetry(std::string url, std::filesystem::path storage_directory, std::string uuid, std::string machine_id,
|
||||||
std::chrono::duration<int64_t> refresh_interval = std::chrono::minutes(10), uint64_t send_every_n = 10);
|
std::chrono::duration<int64_t> refresh_interval = std::chrono::minutes(10), uint64_t send_every_n = 10);
|
||||||
|
|
||||||
void AddCollector(const std::string &name, const std::function<const nlohmann::json(void)> &func);
|
void AddCollector(const std::string &name, const std::function<const nlohmann::json(void)> &func);
|
||||||
|
|
||||||
/// Required to expose run_id to Bolt server.
|
|
||||||
std::string GetRunId() const;
|
|
||||||
|
|
||||||
~Telemetry();
|
~Telemetry();
|
||||||
|
|
||||||
Telemetry(const Telemetry &) = delete;
|
Telemetry(const Telemetry &) = delete;
|
||||||
|
@ -14,6 +14,7 @@ set(utils_src_files
|
|||||||
thread.cpp
|
thread.cpp
|
||||||
thread_pool.cpp
|
thread_pool.cpp
|
||||||
tsc.cpp
|
tsc.cpp
|
||||||
|
system_info.cpp
|
||||||
uuid.cpp)
|
uuid.cpp)
|
||||||
|
|
||||||
find_package(Boost REQUIRED)
|
find_package(Boost REQUIRED)
|
||||||
@ -23,16 +24,10 @@ find_package(Threads REQUIRED)
|
|||||||
|
|
||||||
add_library(mg-utils STATIC ${utils_src_files})
|
add_library(mg-utils STATIC ${utils_src_files})
|
||||||
target_link_libraries(mg-utils PUBLIC Boost::headers fmt::fmt spdlog::spdlog)
|
target_link_libraries(mg-utils PUBLIC Boost::headers fmt::fmt spdlog::spdlog)
|
||||||
target_link_libraries(mg-utils PRIVATE librdtsc stdc++fs Threads::Threads gflags uuid rt)
|
target_link_libraries(mg-utils PRIVATE librdtsc stdc++fs Threads::Threads gflags json uuid rt)
|
||||||
|
|
||||||
set(settings_src_files
|
set(settings_src_files
|
||||||
settings.cpp)
|
settings.cpp)
|
||||||
|
|
||||||
add_library(mg-settings STATIC ${settings_src_files})
|
add_library(mg-settings STATIC ${settings_src_files})
|
||||||
target_link_libraries(mg-settings mg-kvstore mg-slk mg-utils)
|
target_link_libraries(mg-settings mg-kvstore mg-slk mg-utils)
|
||||||
|
|
||||||
set(license_src_files
|
|
||||||
license.cpp)
|
|
||||||
add_library(mg-license STATIC ${license_src_files})
|
|
||||||
target_link_libraries(mg-license mg-settings mg-utils)
|
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ inline uint64_t GetMemoryUsage() {
|
|||||||
pid_t pid = getpid();
|
pid_t pid = getpid();
|
||||||
uint64_t memory = 0;
|
uint64_t memory = 0;
|
||||||
auto statm_data = utils::ReadLines(fmt::format("/proc/{}/statm", pid));
|
auto statm_data = utils::ReadLines(fmt::format("/proc/{}/statm", pid));
|
||||||
if (statm_data.size() >= 1) {
|
if (!statm_data.empty()) {
|
||||||
auto split = utils::Split(statm_data[0]);
|
auto split = utils::Split(statm_data[0]);
|
||||||
if (split.size() >= 2) {
|
if (split.size() >= 2) {
|
||||||
memory = std::stoull(split[1]) * sysconf(_SC_PAGESIZE);
|
memory = std::stoull(split[1]) * sysconf(_SC_PAGESIZE);
|
||||||
|
@ -9,56 +9,35 @@
|
|||||||
// by the Apache License, Version 2.0, included in the file
|
// by the Apache License, Version 2.0, included in the file
|
||||||
// licenses/APL.txt.
|
// licenses/APL.txt.
|
||||||
|
|
||||||
#include "telemetry/system_info.hpp"
|
#include "utils/system_info.hpp"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <sys/utsname.h>
|
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
#include <gflags/gflags.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
|
||||||
#include "utils/file.hpp"
|
#include "utils/file.hpp"
|
||||||
#include "utils/string.hpp"
|
#include "utils/string.hpp"
|
||||||
|
|
||||||
namespace memgraph::telemetry {
|
namespace memgraph::utils {
|
||||||
|
|
||||||
const nlohmann::json GetSystemInfo() {
|
std::string GetMachineId() {
|
||||||
// Get `uname`.
|
#ifdef MG_TELEMETRY_ID_OVERRIDE
|
||||||
struct utsname info;
|
return MG_TELEMETRY_ID_OVERRIDE;
|
||||||
if (uname(&info) != 0) return {};
|
#else
|
||||||
|
// We assume we're on linux and we need to read the machine id from /etc/machine-id
|
||||||
// Parse `/etc/os-release`.
|
const auto machine_id_lines = memgraph::utils::ReadLines("/etc/machine-id");
|
||||||
std::string os_name, os_version, os_full;
|
if (machine_id_lines.size() != 1) {
|
||||||
auto os_data = utils::ReadLines("/etc/os-release");
|
return "UNKNOWN";
|
||||||
for (auto &row : os_data) {
|
|
||||||
auto split = utils::Split(row, "=");
|
|
||||||
if (split.size() < 2) continue;
|
|
||||||
if (split[0] == "NAME") {
|
|
||||||
os_name = utils::Trim(split[1], "\"");
|
|
||||||
} else if (split[0] == "VERSION") {
|
|
||||||
os_version = utils::Trim(split[1], "\"");
|
|
||||||
}
|
|
||||||
os_full = fmt::format("{} {}", os_name, os_version);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse `/proc/cpuinfo`.
|
|
||||||
std::string cpu_model;
|
|
||||||
uint64_t cpu_count = 0;
|
|
||||||
auto cpu_data = utils::ReadLines("/proc/cpuinfo");
|
|
||||||
for (auto &row : cpu_data) {
|
|
||||||
auto tmp = utils::Trim(row);
|
|
||||||
if (tmp == "") {
|
|
||||||
++cpu_count;
|
|
||||||
} else if (utils::StartsWith(tmp, "model name")) {
|
|
||||||
auto split = utils::Split(tmp, ":");
|
|
||||||
if (split.size() != 2) continue;
|
|
||||||
cpu_model = utils::Trim(split[1]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return machine_id_lines[0];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryInfo GetMemoryInfo() {
|
||||||
// Parse `/proc/meminfo`.
|
// Parse `/proc/meminfo`.
|
||||||
nlohmann::json ret;
|
uint64_t memory{0};
|
||||||
uint64_t memory = 0, swap = 0;
|
uint64_t swap{0};
|
||||||
auto mem_data = utils::ReadLines("/proc/meminfo");
|
auto mem_data = utils::ReadLines("/proc/meminfo");
|
||||||
for (auto &row : mem_data) {
|
for (auto &row : mem_data) {
|
||||||
auto tmp = utils::Trim(row);
|
auto tmp = utils::Trim(row);
|
||||||
@ -74,15 +53,55 @@ const nlohmann::json GetSystemInfo() {
|
|||||||
}
|
}
|
||||||
memory *= 1024;
|
memory *= 1024;
|
||||||
swap *= 1024;
|
swap *= 1024;
|
||||||
|
return {memory, swap};
|
||||||
return {{"architecture", info.machine},
|
|
||||||
{"cpu_count", cpu_count},
|
|
||||||
{"cpu_model", cpu_model},
|
|
||||||
{"kernel", fmt::format("{} {}", info.release, info.version)},
|
|
||||||
{"memory", memory},
|
|
||||||
{"os", os_full},
|
|
||||||
{"swap", swap},
|
|
||||||
{"version", gflags::VersionString()}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace memgraph::telemetry
|
CPUInfo GetCPUInfo() {
|
||||||
|
// Parse `/proc/cpuinfo`.
|
||||||
|
std::string cpu_model;
|
||||||
|
uint64_t cpu_count{0};
|
||||||
|
auto cpu_data = utils::ReadLines("/proc/cpuinfo");
|
||||||
|
for (auto &row : cpu_data) {
|
||||||
|
auto tmp = utils::Trim(row);
|
||||||
|
if (tmp.empty()) {
|
||||||
|
++cpu_count;
|
||||||
|
} else if (utils::StartsWith(tmp, "model name")) {
|
||||||
|
auto split = utils::Split(tmp, ":");
|
||||||
|
if (split.size() != 2) continue;
|
||||||
|
cpu_model = utils::Trim(split[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {cpu_model, cpu_count};
|
||||||
|
}
|
||||||
|
|
||||||
|
nlohmann::json GetSystemInfo() {
|
||||||
|
// Get `uname`.
|
||||||
|
struct utsname info;
|
||||||
|
if (uname(&info) != 0) return {};
|
||||||
|
|
||||||
|
// Parse `/etc/os-release`.
|
||||||
|
std::string os_name;
|
||||||
|
std::string os_version;
|
||||||
|
std::string os_full;
|
||||||
|
auto os_data = utils::ReadLines("/etc/os-release");
|
||||||
|
for (auto &row : os_data) {
|
||||||
|
auto split = utils::Split(row, "=");
|
||||||
|
if (split.size() < 2) continue;
|
||||||
|
if (split[0] == "NAME") {
|
||||||
|
os_name = utils::Trim(split[1], "\"");
|
||||||
|
} else if (split[0] == "VERSION") {
|
||||||
|
os_version = utils::Trim(split[1], "\"");
|
||||||
|
}
|
||||||
|
os_full = fmt::format("{} {}", os_name, os_version);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto cpu_info = GetCPUInfo();
|
||||||
|
const auto mem_info = GetMemoryInfo();
|
||||||
|
|
||||||
|
return {{"architecture", info.machine}, {"cpu_count", cpu_info.cpu_count},
|
||||||
|
{"cpu_model", cpu_info.cpu_model}, {"kernel", fmt::format("{} {}", info.release, info.version)},
|
||||||
|
{"memory", mem_info.memory}, {"os", os_full},
|
||||||
|
{"swap", mem_info.swap}, {"version", gflags::VersionString()}};
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace memgraph::utils
|
@ -11,16 +11,33 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include <json/json.hpp>
|
#include <json/json.hpp>
|
||||||
|
|
||||||
namespace memgraph::telemetry {
|
namespace memgraph::utils {
|
||||||
|
|
||||||
// TODO (mferencevic): merge with `utils/sysinfo`
|
struct MemoryInfo {
|
||||||
|
uint64_t memory;
|
||||||
|
uint64_t swap;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CPUInfo {
|
||||||
|
std::string cpu_model;
|
||||||
|
uint64_t cpu_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string GetMachineId();
|
||||||
|
|
||||||
|
MemoryInfo GetMemoryInfo();
|
||||||
|
|
||||||
|
CPUInfo GetCPUInfo();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function returs a dictionary containing some basic system information
|
* This function return a dictionary containing some basic system information
|
||||||
* (eg. operating system name, cpu information, memory information, etc.).
|
* (eg. operating system name, cpu information, memory information, etc.).
|
||||||
*/
|
*/
|
||||||
const nlohmann::json GetSystemInfo();
|
nlohmann::json GetSystemInfo();
|
||||||
|
|
||||||
} // namespace memgraph::telemetry
|
} // namespace memgraph::utils
|
@ -13,24 +13,6 @@ add_subdirectory(auth)
|
|||||||
# lba test binaries
|
# lba test binaries
|
||||||
add_subdirectory(fine_grained_access)
|
add_subdirectory(fine_grained_access)
|
||||||
|
|
||||||
## distributed ha/basic binaries
|
|
||||||
#add_subdirectory(ha/basic)
|
|
||||||
#
|
|
||||||
## distributed ha/constraints binaries
|
|
||||||
#add_subdirectory(ha/constraints)
|
|
||||||
#
|
|
||||||
## distributed ha/index binaries
|
|
||||||
#add_subdirectory(ha/index)
|
|
||||||
#
|
|
||||||
## distributed ha/large_log_entries binaries
|
|
||||||
#add_subdirectory(ha/large_log_entries)
|
|
||||||
#
|
|
||||||
## distributed ha/leader_election binaries
|
|
||||||
#add_subdirectory(ha/leader_election)
|
|
||||||
#
|
|
||||||
## distributed ha/term_updates binaries
|
|
||||||
#add_subdirectory(ha/term_updates)
|
|
||||||
|
|
||||||
# audit test binaries
|
# audit test binaries
|
||||||
add_subdirectory(audit)
|
add_subdirectory(audit)
|
||||||
|
|
||||||
@ -39,3 +21,6 @@ add_subdirectory(ldap)
|
|||||||
|
|
||||||
# mg_import_csv test binaries
|
# mg_import_csv test binaries
|
||||||
add_subdirectory(mg_import_csv)
|
add_subdirectory(mg_import_csv)
|
||||||
|
|
||||||
|
# license_check test binaries
|
||||||
|
add_subdirectory(license_info)
|
||||||
|
6
tests/integration/license_info/CMakeLists.txt
Normal file
6
tests/integration/license_info/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
set(target_name memgraph__integration__license_info)
|
||||||
|
set(client_target_name ${target_name}__client)
|
||||||
|
|
||||||
|
add_executable(${client_target_name} client.cpp)
|
||||||
|
set_target_properties(${client_target_name} PROPERTIES OUTPUT_NAME client)
|
||||||
|
target_link_libraries(${client_target_name} mg-requests mg-license mg-utils)
|
62
tests/integration/license_info/client.cpp
Normal file
62
tests/integration/license_info/client.cpp
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
// Copyright 2022 Memgraph Ltd.
|
||||||
|
//
|
||||||
|
// Use of this software is governed by the Business Source License
|
||||||
|
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||||
|
// License, and you may not use this file except in compliance with the Business Source License.
|
||||||
|
//
|
||||||
|
// As of the Change Date specified in that file, in accordance with
|
||||||
|
// the Business Source License, use of this software will be governed
|
||||||
|
// by the Apache License, Version 2.0, included in the file
|
||||||
|
// licenses/APL.txt.
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <gflags/gflags.h>
|
||||||
|
|
||||||
|
#include "license/license.hpp"
|
||||||
|
#include "license/license_sender.hpp"
|
||||||
|
#include "requests/requests.hpp"
|
||||||
|
#include "spdlog/spdlog.h"
|
||||||
|
#include "utils/logging.hpp"
|
||||||
|
#include "utils/synchronized.hpp"
|
||||||
|
#include "utils/system_info.hpp"
|
||||||
|
#include "utils/uuid.hpp"
|
||||||
|
|
||||||
|
DEFINE_string(endpoint, "http://127.0.0.1:5500/", "Endpoint that should be used for the test.");
|
||||||
|
DEFINE_string(license_type, "enterprise", "License type; can be oem or enterprise.");
|
||||||
|
DEFINE_int64(interval, 1, "Interval used for reporting telemetry in seconds.");
|
||||||
|
DEFINE_int64(duration, 10, "Duration of the test in seconds.");
|
||||||
|
|
||||||
|
memgraph::license::LicenseType StringToLicenseType(const std::string_view license_type) {
|
||||||
|
if (license_type == "enterprise") {
|
||||||
|
return memgraph::license::LicenseType::ENTERPRISE;
|
||||||
|
}
|
||||||
|
if (license_type == "oem") {
|
||||||
|
return memgraph::license::LicenseType::OEM;
|
||||||
|
}
|
||||||
|
spdlog::critical("Invalid license type!");
|
||||||
|
std::terminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
gflags::SetVersionString("license-info");
|
||||||
|
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
||||||
|
|
||||||
|
memgraph::requests::Init();
|
||||||
|
|
||||||
|
memgraph::license::License license{"Memgraph", 0, 0, StringToLicenseType(FLAGS_license_type)};
|
||||||
|
memgraph::utils::Synchronized<std::optional<memgraph::license::LicenseInfo>, memgraph::utils::SpinLock> license_info{
|
||||||
|
memgraph::license::LicenseInfo{"mg-testkey", "Memgraph"}};
|
||||||
|
license_info.WithLock([license = std::move(license)](auto &license_info) {
|
||||||
|
license_info->license = license;
|
||||||
|
license_info->is_valid = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
memgraph::license::LicenseInfoSender license_sender(FLAGS_endpoint, memgraph::utils::GenerateUUID(),
|
||||||
|
memgraph::utils::GetMachineId(), 10000000, license_info,
|
||||||
|
std::chrono::seconds(FLAGS_interval));
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds(FLAGS_duration));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
96
tests/integration/license_info/runner.py
Executable file
96
tests/integration/license_info/runner.py
Executable file
@ -0,0 +1,96 @@
|
|||||||
|
#!/usr/bin/python3 -u
|
||||||
|
|
||||||
|
# Copyright 2021 Memgraph Ltd.
|
||||||
|
#
|
||||||
|
# Use of this software is governed by the Business Source License
|
||||||
|
# included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||||
|
# License, and you may not use this file except in compliance with the Business Source License.
|
||||||
|
#
|
||||||
|
# As of the Change Date specified in that file, in accordance with
|
||||||
|
# the Business Source License, use of this software will be governed
|
||||||
|
# by the Apache License, Version 2.0, included in the file
|
||||||
|
# licenses/APL.txt.
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
PROJECT_DIR = os.path.normpath(os.path.join(SCRIPT_DIR, "..", "..", ".."))
|
||||||
|
|
||||||
|
|
||||||
|
def execute_test(**kwargs):
|
||||||
|
client_binary = kwargs.pop("client")
|
||||||
|
server_binary = kwargs.pop("server")
|
||||||
|
|
||||||
|
start_server = kwargs.pop("start_server", True)
|
||||||
|
interval = kwargs.pop("interval", 1)
|
||||||
|
duration = kwargs.pop("duration", 5)
|
||||||
|
license_type = kwargs.pop("license-type", "enterprise")
|
||||||
|
|
||||||
|
timeout = duration * 2 if "hang" not in kwargs else duration * 2 + 60
|
||||||
|
success = False
|
||||||
|
|
||||||
|
client_args = [client_binary, "--interval", interval, "--duration", duration, "--license-type", license_type]
|
||||||
|
|
||||||
|
server = None
|
||||||
|
if start_server:
|
||||||
|
server = subprocess.Popen(server_binary)
|
||||||
|
time.sleep(0.4)
|
||||||
|
assert server.poll() is None, "Server process died prematurely!"
|
||||||
|
|
||||||
|
try:
|
||||||
|
subprocess.run(list(map(str, client_args)), timeout=timeout, check=True)
|
||||||
|
finally:
|
||||||
|
if server is None:
|
||||||
|
success = True
|
||||||
|
else:
|
||||||
|
server.terminate()
|
||||||
|
try:
|
||||||
|
success = server.wait(timeout=5) == 0
|
||||||
|
success = True
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
server.kill()
|
||||||
|
return success
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
server_binary = os.path.join(SCRIPT_DIR, "server.py")
|
||||||
|
client_binary = os.path.join(PROJECT_DIR, "build", "tests", "integration", "license_info", "client")
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("--client", default=client_binary)
|
||||||
|
parser.add_argument("--server", default=server_binary)
|
||||||
|
parser.add_argument("--server-url", default="127.0.0.1")
|
||||||
|
parser.add_argument("--server-port", default="5500")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
tests = [
|
||||||
|
{"interval": 2},
|
||||||
|
{"duration": 10},
|
||||||
|
{"interval": 2, "duration": 10},
|
||||||
|
{"license-type": "oem"},
|
||||||
|
{"license-type": "enterprise"},
|
||||||
|
]
|
||||||
|
for test in tests:
|
||||||
|
print("\033[1;36m~~ Executing test with arguments:", json.dumps(test, sort_keys=True), "~~\033[0m")
|
||||||
|
|
||||||
|
try:
|
||||||
|
success = execute_test(client=args.client, server=args.server, **test)
|
||||||
|
except Exception as e:
|
||||||
|
print("\033[1;33m", e, "\033[0m", sep="")
|
||||||
|
success = False
|
||||||
|
|
||||||
|
if not success:
|
||||||
|
print("\033[1;31m~~", "Test failed!", "~~\033[0m")
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
print("\033[1;32m~~", "Test ok!", "~~\033[0m")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
69
tests/integration/license_info/server.py
Executable file
69
tests/integration/license_info/server.py
Executable file
@ -0,0 +1,69 @@
|
|||||||
|
#!/usr/bin/python3 -u
|
||||||
|
|
||||||
|
# Copyright 2021 Memgraph Ltd.
|
||||||
|
#
|
||||||
|
# Use of this software is governed by the Business Source License
|
||||||
|
# included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||||
|
# License, and you may not use this file except in compliance with the Business Source License.
|
||||||
|
#
|
||||||
|
# As of the Change Date specified in that file, in accordance with
|
||||||
|
# the Business Source License, use of this software will be governed
|
||||||
|
# by the Apache License, Version 2.0, included in the file
|
||||||
|
# licenses/APL.txt.
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
from http.server import HTTPServer, SimpleHTTPRequestHandler
|
||||||
|
|
||||||
|
EXPECTED_LICENSE_INFO_FIELDS = {
|
||||||
|
"run_id": str,
|
||||||
|
"machine_id": str,
|
||||||
|
"type": str,
|
||||||
|
"license_type": str,
|
||||||
|
"license_key": str,
|
||||||
|
"organization": str,
|
||||||
|
"valid": bool,
|
||||||
|
"physical_memory_size": int,
|
||||||
|
"swap_memory_size": int,
|
||||||
|
"memory_used": int,
|
||||||
|
"runtime_memory_limit": int,
|
||||||
|
"license_memory_limit": int,
|
||||||
|
"timestamp": float,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ServerHandler(SimpleHTTPRequestHandler):
|
||||||
|
def do_POST(self):
|
||||||
|
assert self.headers["user-agent"] == "memgraph/license-info", f"The header is {self.headers['user-agent']}"
|
||||||
|
assert self.headers["accept"] == "application/json", f"The header is {self.headers['accept']}"
|
||||||
|
assert self.headers["content-type"] == "application/json", f"The header is {self.headers['content-type']}"
|
||||||
|
|
||||||
|
content_len = int(self.headers.get("content-length", 0))
|
||||||
|
data = json.loads(self.rfile.read(content_len).decode("utf-8"))
|
||||||
|
|
||||||
|
assert isinstance(data, dict)
|
||||||
|
|
||||||
|
for expected_field, expected_type in EXPECTED_LICENSE_INFO_FIELDS.items():
|
||||||
|
assert expected_field in data, f"Field {expected_field} not found in received data"
|
||||||
|
assert isinstance(
|
||||||
|
data[expected_field], expected_type
|
||||||
|
), f"Field {expected_field} is not correct type: expected {expected_type} got {type(data[expected_field])}"
|
||||||
|
assert len(EXPECTED_LICENSE_INFO_FIELDS) == len(data), "Expected data size does not match received"
|
||||||
|
|
||||||
|
self.send_response(200)
|
||||||
|
self.end_headers()
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("--address", type=str, default="127.0.0.1")
|
||||||
|
parser.add_argument("--port", type=int, default=5500)
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
with HTTPServer((args.address, args.port), ServerHandler) as srv:
|
||||||
|
print(f"Serving HTTP server at {args.address}:{args.port}")
|
||||||
|
srv.serve_forever()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
@ -3,4 +3,4 @@ set(client_target_name ${target_name}__client)
|
|||||||
|
|
||||||
add_executable(${client_target_name} client.cpp)
|
add_executable(${client_target_name} client.cpp)
|
||||||
set_target_properties(${client_target_name} PROPERTIES OUTPUT_NAME client)
|
set_target_properties(${client_target_name} PROPERTIES OUTPUT_NAME client)
|
||||||
target_link_libraries(${client_target_name} mg-requests telemetry_lib)
|
target_link_libraries(${client_target_name} mg-requests mg-telemetry)
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
#include "requests/requests.hpp"
|
#include "requests/requests.hpp"
|
||||||
#include "telemetry/telemetry.hpp"
|
#include "telemetry/telemetry.hpp"
|
||||||
|
#include "utils/system_info.hpp"
|
||||||
|
#include "utils/uuid.hpp"
|
||||||
|
|
||||||
DEFINE_string(endpoint, "http://127.0.0.1:9000/", "Endpoint that should be used for the test.");
|
DEFINE_string(endpoint, "http://127.0.0.1:9000/", "Endpoint that should be used for the test.");
|
||||||
DEFINE_int64(interval, 1, "Interval used for reporting telemetry in seconds.");
|
DEFINE_int64(interval, 1, "Interval used for reporting telemetry in seconds.");
|
||||||
@ -24,8 +26,8 @@ int main(int argc, char **argv) {
|
|||||||
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
||||||
|
|
||||||
memgraph::requests::Init();
|
memgraph::requests::Init();
|
||||||
memgraph::telemetry::Telemetry telemetry(FLAGS_endpoint, FLAGS_storage_directory,
|
memgraph::telemetry::Telemetry telemetry(FLAGS_endpoint, FLAGS_storage_directory, memgraph::utils::GenerateUUID(),
|
||||||
std::chrono::seconds(FLAGS_interval), 1);
|
memgraph::utils::GetMachineId(), std::chrono::seconds(FLAGS_interval), 1);
|
||||||
|
|
||||||
uint64_t counter = 0;
|
uint64_t counter = 0;
|
||||||
telemetry.AddCollector("db", [&counter]() -> nlohmann::json {
|
telemetry.AddCollector("db", [&counter]() -> nlohmann::json {
|
||||||
|
@ -36,8 +36,7 @@ def execute_test(**kwargs):
|
|||||||
timeout = duration * 2 if "hang" not in kwargs else duration * 2 + 60
|
timeout = duration * 2 if "hang" not in kwargs else duration * 2 + 60
|
||||||
success = False
|
success = False
|
||||||
|
|
||||||
server_args = [server_binary, "--interval", interval,
|
server_args = [server_binary, "--interval", interval, "--duration", duration]
|
||||||
"--duration", duration]
|
|
||||||
for flag, value in kwargs.items():
|
for flag, value in kwargs.items():
|
||||||
flag = "--" + flag.replace("_", "-")
|
flag = "--" + flag.replace("_", "-")
|
||||||
# We handle boolean flags here. The type of value must be `bool`, and
|
# We handle boolean flags here. The type of value must be `bool`, and
|
||||||
@ -48,9 +47,15 @@ def execute_test(**kwargs):
|
|||||||
else:
|
else:
|
||||||
server_args.extend([flag, value])
|
server_args.extend([flag, value])
|
||||||
|
|
||||||
client_args = [client_binary, "--interval", interval,
|
client_args = [
|
||||||
"--duration", duration,
|
client_binary,
|
||||||
"--storage-directory", storage_directory]
|
"--interval",
|
||||||
|
interval,
|
||||||
|
"--duration",
|
||||||
|
duration,
|
||||||
|
"--storage-directory",
|
||||||
|
storage_directory,
|
||||||
|
]
|
||||||
if endpoint:
|
if endpoint:
|
||||||
client_args.extend(["--endpoint", endpoint])
|
client_args.extend(["--endpoint", endpoint])
|
||||||
|
|
||||||
@ -61,8 +66,7 @@ def execute_test(**kwargs):
|
|||||||
assert server.poll() is None, "Server process died prematurely!"
|
assert server.poll() is None, "Server process died prematurely!"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
subprocess.run(list(map(str, client_args)), timeout=timeout,
|
subprocess.run(list(map(str, client_args)), timeout=timeout, check=True)
|
||||||
check=True)
|
|
||||||
finally:
|
finally:
|
||||||
if server is None:
|
if server is None:
|
||||||
success = True
|
success = True
|
||||||
@ -88,16 +92,14 @@ TESTS = [
|
|||||||
{"endpoint": "http://127.0.0.1:9000/nonexistant/", "no_check": True},
|
{"endpoint": "http://127.0.0.1:9000/nonexistant/", "no_check": True},
|
||||||
{"start_server": False},
|
{"start_server": False},
|
||||||
{"startups": 4, "no_check_duration": True}, # the last 3 tests failed
|
{"startups": 4, "no_check_duration": True}, # the last 3 tests failed
|
||||||
# to send any data + this test
|
# to send any data + this test
|
||||||
{"add_garbage": True}
|
{"add_garbage": True},
|
||||||
]
|
]
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
server_binary = os.path.join(SCRIPT_DIR, "server.py")
|
server_binary = os.path.join(SCRIPT_DIR, "server.py")
|
||||||
client_binary = os.path.join(PROJECT_DIR, "build", "tests",
|
client_binary = os.path.join(PROJECT_DIR, "build", "tests", "integration", "telemetry", "client")
|
||||||
"integration", "telemetry", "client")
|
kvstore_console_binary = os.path.join(PROJECT_DIR, "build", "tests", "manual", "kvstore_console")
|
||||||
kvstore_console_binary = os.path.join(PROJECT_DIR, "build", "tests",
|
|
||||||
"manual", "kvstore_console")
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument("--client", default=client_binary)
|
parser.add_argument("--client", default=client_binary)
|
||||||
@ -108,19 +110,17 @@ if __name__ == "__main__":
|
|||||||
storage = tempfile.TemporaryDirectory()
|
storage = tempfile.TemporaryDirectory()
|
||||||
|
|
||||||
for test in TESTS:
|
for test in TESTS:
|
||||||
print("\033[1;36m~~ Executing test with arguments:",
|
print("\033[1;36m~~ Executing test with arguments:", json.dumps(test, sort_keys=True), "~~\033[0m")
|
||||||
json.dumps(test, sort_keys=True), "~~\033[0m")
|
|
||||||
|
|
||||||
if test.pop("add_garbage", False):
|
if test.pop("add_garbage", False):
|
||||||
proc = subprocess.Popen([args.kvstore_console, "--path",
|
proc = subprocess.Popen(
|
||||||
storage.name], stdin=subprocess.PIPE,
|
[args.kvstore_console, "--path", storage.name], stdin=subprocess.PIPE, stdout=subprocess.DEVNULL
|
||||||
stdout=subprocess.DEVNULL)
|
)
|
||||||
proc.communicate("put garbage garbage".encode("utf-8"))
|
proc.communicate("put garbage garbage".encode("utf-8"))
|
||||||
assert proc.wait() == 0
|
assert proc.wait() == 0
|
||||||
|
|
||||||
try:
|
try:
|
||||||
success = execute_test(client=args.client, server=args.server,
|
success = execute_test(client=args.client, server=args.server, storage=storage.name, **test)
|
||||||
storage=storage.name, **test)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("\033[1;33m", e, "\033[0m", sep="")
|
print("\033[1;33m", e, "\033[0m", sep="")
|
||||||
success = False
|
success = False
|
||||||
|
@ -12,13 +12,12 @@
|
|||||||
# licenses/APL.txt.
|
# licenses/APL.txt.
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import itertools
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import signal
|
import signal
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import itertools
|
|
||||||
|
|
||||||
from http.server import BaseHTTPRequestHandler, HTTPServer
|
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||||
|
|
||||||
|
|
||||||
@ -46,7 +45,7 @@ def build_handler(storage, args):
|
|||||||
assert self.headers["accept"] == "application/json"
|
assert self.headers["accept"] == "application/json"
|
||||||
assert self.headers["content-type"] == "application/json"
|
assert self.headers["content-type"] == "application/json"
|
||||||
|
|
||||||
content_len = int(self.headers.get('content-length', 0))
|
content_len = int(self.headers.get("content-length", 0))
|
||||||
data = json.loads(self.rfile.read(content_len).decode("utf-8"))
|
data = json.loads(self.rfile.read(content_len).decode("utf-8"))
|
||||||
|
|
||||||
if self.path not in [args.path, args.redirect_path]:
|
if self.path not in [args.path, args.redirect_path]:
|
||||||
@ -70,6 +69,7 @@ def build_handler(storage, args):
|
|||||||
assert type(item) == dict
|
assert type(item) == dict
|
||||||
assert "event" in item
|
assert "event" in item
|
||||||
assert "run_id" in item
|
assert "run_id" in item
|
||||||
|
assert "type" in item
|
||||||
assert "machine_id" in item
|
assert "machine_id" in item
|
||||||
assert "data" in item
|
assert "data" in item
|
||||||
assert "timestamp" in item
|
assert "timestamp" in item
|
||||||
@ -188,11 +188,11 @@ if __name__ == "__main__":
|
|||||||
startups[-1].append(item)
|
startups[-1].append(item)
|
||||||
|
|
||||||
# Check that there were the correct number of startups.
|
# Check that there were the correct number of startups.
|
||||||
assert len(startups) == args.startups
|
assert len(startups) == args.startups, f"Expected: {args.startups}, actual: {len(startups)}"
|
||||||
|
|
||||||
# Verify each startup.
|
# Verify each startup.
|
||||||
for startup in startups:
|
for startup in startups:
|
||||||
verify_storage(startup, args)
|
verify_storage(startup, args)
|
||||||
|
|
||||||
# machine id has to be same for every run on the same machine
|
# machine id has to be same for every run on the same machine
|
||||||
assert len(set(map(lambda x: x['machine_id'], itertools.chain(*startups)))) == 1
|
assert len(set(map(lambda x: x["machine_id"], itertools.chain(*startups)))) == 1
|
||||||
|
@ -10,11 +10,11 @@
|
|||||||
// licenses/APL.txt.
|
// licenses/APL.txt.
|
||||||
|
|
||||||
#include "communication/result_stream_faker.hpp"
|
#include "communication/result_stream_faker.hpp"
|
||||||
|
#include "license/license.hpp"
|
||||||
#include "query/config.hpp"
|
#include "query/config.hpp"
|
||||||
#include "query/interpreter.hpp"
|
#include "query/interpreter.hpp"
|
||||||
#include "storage/v2/isolation_level.hpp"
|
#include "storage/v2/isolation_level.hpp"
|
||||||
#include "storage/v2/storage.hpp"
|
#include "storage/v2/storage.hpp"
|
||||||
#include "utils/license.hpp"
|
|
||||||
#include "utils/on_scope_exit.hpp"
|
#include "utils/on_scope_exit.hpp"
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
@ -30,7 +30,7 @@ int main(int argc, char *argv[]) {
|
|||||||
auto data_directory = std::filesystem::temp_directory_path() / "single_query_test";
|
auto data_directory = std::filesystem::temp_directory_path() / "single_query_test";
|
||||||
memgraph::utils::OnScopeExit([&data_directory] { std::filesystem::remove_all(data_directory); });
|
memgraph::utils::OnScopeExit([&data_directory] { std::filesystem::remove_all(data_directory); });
|
||||||
|
|
||||||
memgraph::utils::license::global_license_checker.EnableTesting();
|
memgraph::license::global_license_checker.EnableTesting();
|
||||||
memgraph::query::InterpreterContext interpreter_context{&db, memgraph::query::InterpreterConfig{}, data_directory};
|
memgraph::query::InterpreterContext interpreter_context{&db, memgraph::query::InterpreterConfig{}, data_directory};
|
||||||
memgraph::query::Interpreter interpreter{&interpreter_context};
|
memgraph::query::Interpreter interpreter{&interpreter_context};
|
||||||
|
|
||||||
|
@ -269,8 +269,8 @@ target_link_libraries(${test_prefix}utils_csv_parsing mg-utils fmt)
|
|||||||
add_unit_test(utils_async_timer.cpp)
|
add_unit_test(utils_async_timer.cpp)
|
||||||
target_link_libraries(${test_prefix}utils_async_timer mg-utils)
|
target_link_libraries(${test_prefix}utils_async_timer mg-utils)
|
||||||
|
|
||||||
add_unit_test(utils_license.cpp)
|
add_unit_test(license.cpp)
|
||||||
target_link_libraries(${test_prefix}utils_license mg-utils mg-license)
|
target_link_libraries(${test_prefix}license mg-utils mg-license)
|
||||||
|
|
||||||
add_unit_test(utils_settings.cpp)
|
add_unit_test(utils_settings.cpp)
|
||||||
target_link_libraries(${test_prefix}utils_settings mg-utils mg-settings)
|
target_link_libraries(${test_prefix}utils_settings mg-utils mg-settings)
|
||||||
|
@ -19,9 +19,9 @@
|
|||||||
#include "auth/auth.hpp"
|
#include "auth/auth.hpp"
|
||||||
#include "auth/crypto.hpp"
|
#include "auth/crypto.hpp"
|
||||||
#include "auth/models.hpp"
|
#include "auth/models.hpp"
|
||||||
|
#include "license/license.hpp"
|
||||||
#include "utils/cast.hpp"
|
#include "utils/cast.hpp"
|
||||||
#include "utils/file.hpp"
|
#include "utils/file.hpp"
|
||||||
#include "utils/license.hpp"
|
|
||||||
|
|
||||||
using namespace memgraph::auth;
|
using namespace memgraph::auth;
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
@ -36,7 +36,7 @@ class AuthWithStorage : public ::testing::Test {
|
|||||||
FLAGS_auth_password_permit_null = true;
|
FLAGS_auth_password_permit_null = true;
|
||||||
FLAGS_auth_password_strength_regex = ".+";
|
FLAGS_auth_password_strength_regex = ".+";
|
||||||
|
|
||||||
memgraph::utils::license::global_license_checker.EnableTesting();
|
memgraph::license::global_license_checker.EnableTesting();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void TearDown() { fs::remove_all(test_folder_); }
|
virtual void TearDown() { fs::remove_all(test_folder_); }
|
||||||
|
@ -15,9 +15,9 @@
|
|||||||
#include "auth/models.hpp"
|
#include "auth/models.hpp"
|
||||||
#include "glue/auth_checker.hpp"
|
#include "glue/auth_checker.hpp"
|
||||||
|
|
||||||
|
#include "license/license.hpp"
|
||||||
#include "query_plan_common.hpp"
|
#include "query_plan_common.hpp"
|
||||||
#include "storage/v2/view.hpp"
|
#include "storage/v2/view.hpp"
|
||||||
#include "utils/license.hpp"
|
|
||||||
|
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
class FineGrainedAuthCheckerFixture : public testing::Test {
|
class FineGrainedAuthCheckerFixture : public testing::Test {
|
||||||
@ -39,7 +39,7 @@ class FineGrainedAuthCheckerFixture : public testing::Test {
|
|||||||
memgraph::query::EdgeAccessor r4{*dba.InsertEdge(&v1, &v3, edge_type_two)};
|
memgraph::query::EdgeAccessor r4{*dba.InsertEdge(&v1, &v3, edge_type_two)};
|
||||||
|
|
||||||
void SetUp() override {
|
void SetUp() override {
|
||||||
memgraph::utils::license::global_license_checker.EnableTesting();
|
memgraph::license::global_license_checker.EnableTesting();
|
||||||
ASSERT_TRUE(v1.AddLabel(dba.NameToLabel("l1")).HasValue());
|
ASSERT_TRUE(v1.AddLabel(dba.NameToLabel("l1")).HasValue());
|
||||||
ASSERT_TRUE(v2.AddLabel(dba.NameToLabel("l2")).HasValue());
|
ASSERT_TRUE(v2.AddLabel(dba.NameToLabel("l2")).HasValue());
|
||||||
ASSERT_TRUE(v3.AddLabel(dba.NameToLabel("l3")).HasValue());
|
ASSERT_TRUE(v3.AddLabel(dba.NameToLabel("l3")).HasValue());
|
||||||
|
@ -37,7 +37,7 @@ class AuthQueryHandlerFixture : public testing::Test {
|
|||||||
#endif
|
#endif
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
memgraph::utils::EnsureDir(test_folder_);
|
memgraph::utils::EnsureDir(test_folder_);
|
||||||
memgraph::utils::license::global_license_checker.EnableTesting();
|
memgraph::license::global_license_checker.EnableTesting();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void TearDown() {
|
virtual void TearDown() {
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#include <gtest/internal/gtest-param-util-generated.h>
|
#include <gtest/internal/gtest-param-util-generated.h>
|
||||||
|
|
||||||
#include "auth/models.hpp"
|
#include "auth/models.hpp"
|
||||||
#include "utils/license.hpp"
|
#include "license/license.hpp"
|
||||||
|
|
||||||
using namespace memgraph::query;
|
using namespace memgraph::query;
|
||||||
using namespace memgraph::query::plan;
|
using namespace memgraph::query::plan;
|
||||||
@ -80,7 +80,7 @@ class FineGrainedBfsTest
|
|||||||
std::tuple<int, int, EdgeAtom::Direction, std::vector<std::string>, bool, FineGrainedTestType>> {
|
std::tuple<int, int, EdgeAtom::Direction, std::vector<std::string>, bool, FineGrainedTestType>> {
|
||||||
public:
|
public:
|
||||||
static void SetUpTestCase() {
|
static void SetUpTestCase() {
|
||||||
memgraph::utils::license::global_license_checker.EnableTesting();
|
memgraph::license::global_license_checker.EnableTesting();
|
||||||
db_ = std::make_unique<VertexDb>();
|
db_ = std::make_unique<VertexDb>();
|
||||||
}
|
}
|
||||||
static void TearDownTestCase() { db_ = nullptr; }
|
static void TearDownTestCase() { db_ = nullptr; }
|
||||||
|
@ -480,6 +480,39 @@ TEST_F(InterpreterTest, ShortestPath) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(InterpreterTest, AllShortestById) {
|
||||||
|
auto stream_init = Interpret(
|
||||||
|
"CREATE (n:A {x: 1}), (m:B {x: 2}), (l:C {x: 3}), (k:D {x: 4}), (n)-[:r1 {w: 1 "
|
||||||
|
"}]->(m)-[:r2 {w: 2}]->(l), (n)-[:r3 {w: 4}]->(l), (k)-[:r4 {w: 3}]->(l) return id(n), id(l)");
|
||||||
|
|
||||||
|
auto id_n = stream_init.GetResults().front()[0].ValueInt();
|
||||||
|
auto id_l = stream_init.GetResults().front()[1].ValueInt();
|
||||||
|
|
||||||
|
auto stream = Interpret(
|
||||||
|
fmt::format("MATCH (n)-[e *allshortest 5 (e, n | e.w) ]->(l) WHERE id(n)={} AND id(l)={} return e", id_n, id_l));
|
||||||
|
|
||||||
|
ASSERT_EQ(stream.GetHeader().size(), 1U);
|
||||||
|
EXPECT_EQ(stream.GetHeader()[0], "e");
|
||||||
|
ASSERT_EQ(stream.GetResults().size(), 1U);
|
||||||
|
|
||||||
|
auto dba = db_.Access();
|
||||||
|
std::vector<std::string> expected_result = {"r1", "r2"};
|
||||||
|
|
||||||
|
const auto &result = stream.GetResults()[0];
|
||||||
|
const auto &edges = ToEdgeList(result[0]);
|
||||||
|
|
||||||
|
std::vector<std::string> datum;
|
||||||
|
datum.reserve(edges.size());
|
||||||
|
|
||||||
|
for (const auto &edge : edges) {
|
||||||
|
datum.push_back(edge.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_TRUE(expected_result == datum);
|
||||||
|
|
||||||
|
Interpret("MATCH (n) DETACH DELETE n");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(InterpreterTest, CreateLabelIndexInMulticommandTransaction) {
|
TEST_F(InterpreterTest, CreateLabelIndexInMulticommandTransaction) {
|
||||||
Interpret("BEGIN");
|
Interpret("BEGIN");
|
||||||
ASSERT_THROW(Interpret("CREATE INDEX ON :X"), memgraph::query::IndexInMulticommandTxException);
|
ASSERT_THROW(Interpret("CREATE INDEX ON :X"), memgraph::query::IndexInMulticommandTxException);
|
||||||
|
@ -10,8 +10,9 @@
|
|||||||
// licenses/APL.txt.
|
// licenses/APL.txt.
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
#include "utils/license.hpp"
|
#include "license/license.hpp"
|
||||||
#include "utils/settings.hpp"
|
#include "utils/settings.hpp"
|
||||||
|
|
||||||
class LicenseTest : public ::testing::Test {
|
class LicenseTest : public ::testing::Test {
|
||||||
@ -21,7 +22,7 @@ class LicenseTest : public ::testing::Test {
|
|||||||
settings->Initialize(settings_directory);
|
settings->Initialize(settings_directory);
|
||||||
|
|
||||||
license_checker.emplace();
|
license_checker.emplace();
|
||||||
memgraph::utils::license::RegisterLicenseSettings(*license_checker, *settings);
|
memgraph::license::RegisterLicenseSettings(*license_checker, *settings);
|
||||||
|
|
||||||
license_checker->StartBackgroundLicenseChecker(*settings);
|
license_checker->StartBackgroundLicenseChecker(*settings);
|
||||||
}
|
}
|
||||||
@ -33,24 +34,25 @@ class LicenseTest : public ::testing::Test {
|
|||||||
const std::filesystem::path settings_directory{test_directory / "settings"};
|
const std::filesystem::path settings_directory{test_directory / "settings"};
|
||||||
|
|
||||||
void CheckLicenseValidity(const bool expected_valid) {
|
void CheckLicenseValidity(const bool expected_valid) {
|
||||||
ASSERT_EQ(!license_checker->IsValidLicense(*settings).HasError(), expected_valid);
|
ASSERT_EQ(!license_checker->IsEnterpriseValid(*settings).HasError(), expected_valid);
|
||||||
ASSERT_EQ(license_checker->IsValidLicenseFast(), expected_valid);
|
ASSERT_EQ(license_checker->IsEnterpriseValidFast(), expected_valid);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<memgraph::utils::Settings> settings;
|
std::optional<memgraph::utils::Settings> settings;
|
||||||
std::optional<memgraph::utils::license::LicenseChecker> license_checker;
|
std::optional<memgraph::license::LicenseChecker> license_checker;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(LicenseTest, EncodeDecode) {
|
TEST_F(LicenseTest, EncodeDecode) {
|
||||||
const std::array licenses = {
|
const std::array licenses = {
|
||||||
memgraph::utils::license::License{"Organization", 1, 2},
|
memgraph::license::License{"Organization", 1, 2, memgraph::license::LicenseType::OEM},
|
||||||
memgraph::utils::license::License{"", -1, 0},
|
memgraph::license::License{"", -1, 0, memgraph::license::LicenseType::ENTERPRISE},
|
||||||
memgraph::utils::license::License{"Some very long name for the organization Ltd", -999, -9999},
|
memgraph::license::License{"Some very long name for the organization Ltd", -999, -9999,
|
||||||
|
memgraph::license::LicenseType::ENTERPRISE},
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const auto &license : licenses) {
|
for (const auto &license : licenses) {
|
||||||
const auto result = memgraph::utils::license::Encode(license);
|
const auto result = memgraph::license::Encode(license);
|
||||||
auto maybe_license = memgraph::utils::license::Decode(result);
|
auto maybe_license = memgraph::license::Decode(result);
|
||||||
ASSERT_TRUE(maybe_license);
|
ASSERT_TRUE(maybe_license);
|
||||||
ASSERT_EQ(*maybe_license, license);
|
ASSERT_EQ(*maybe_license, license);
|
||||||
}
|
}
|
||||||
@ -69,10 +71,9 @@ TEST_F(LicenseTest, TestingFlag) {
|
|||||||
|
|
||||||
TEST_F(LicenseTest, LicenseOrganizationName) {
|
TEST_F(LicenseTest, LicenseOrganizationName) {
|
||||||
const std::string organization_name{"Memgraph"};
|
const std::string organization_name{"Memgraph"};
|
||||||
memgraph::utils::license::License license{
|
memgraph::license::License license{organization_name, 0, 0, memgraph::license::LicenseType::ENTERPRISE};
|
||||||
.organization_name = organization_name, .valid_until = 0, .memory_limit = 0};
|
|
||||||
|
|
||||||
settings->SetValue("enterprise.license", memgraph::utils::license::Encode(license));
|
settings->SetValue("enterprise.license", memgraph::license::Encode(license));
|
||||||
settings->SetValue("organization.name", organization_name);
|
settings->SetValue("organization.name", organization_name);
|
||||||
CheckLicenseValidity(true);
|
CheckLicenseValidity(true);
|
||||||
|
|
||||||
@ -91,22 +92,21 @@ TEST_F(LicenseTest, Expiration) {
|
|||||||
std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch());
|
std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch());
|
||||||
const auto delta = std::chrono::seconds(1);
|
const auto delta = std::chrono::seconds(1);
|
||||||
const auto valid_until = now + delta;
|
const auto valid_until = now + delta;
|
||||||
memgraph::utils::license::License license{
|
memgraph::license::License license{organization_name, valid_until.count(), 0,
|
||||||
.organization_name = organization_name, .valid_until = valid_until.count(), .memory_limit = 0};
|
memgraph::license::LicenseType::ENTERPRISE};
|
||||||
|
|
||||||
settings->SetValue("enterprise.license", memgraph::utils::license::Encode(license));
|
settings->SetValue("enterprise.license", memgraph::license::Encode(license));
|
||||||
settings->SetValue("organization.name", organization_name);
|
settings->SetValue("organization.name", organization_name);
|
||||||
CheckLicenseValidity(true);
|
CheckLicenseValidity(true);
|
||||||
|
|
||||||
std::this_thread::sleep_for(delta + std::chrono::seconds(1));
|
std::this_thread::sleep_for(delta + std::chrono::seconds(1));
|
||||||
ASSERT_TRUE(license_checker->IsValidLicense(*settings).HasError());
|
ASSERT_TRUE(license_checker->IsEnterpriseValid(*settings).HasError());
|
||||||
// We can't check fast checker because it has unknown refresh rate
|
// We can't check fast checker because it has unknown refresh rate
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
SCOPED_TRACE("License with valid_until = 0 is always valid");
|
SCOPED_TRACE("License with valid_until = 0 is always valid");
|
||||||
memgraph::utils::license::License license{
|
memgraph::license::License license{organization_name, 0, 0, memgraph::license::LicenseType::ENTERPRISE};
|
||||||
.organization_name = organization_name, .valid_until = 0, .memory_limit = 0};
|
settings->SetValue("enterprise.license", memgraph::license::Encode(license));
|
||||||
settings->SetValue("enterprise.license", memgraph::utils::license::Encode(license));
|
|
||||||
settings->SetValue("organization.name", organization_name);
|
settings->SetValue("organization.name", organization_name);
|
||||||
CheckLicenseValidity(true);
|
CheckLicenseValidity(true);
|
||||||
}
|
}
|
||||||
@ -116,9 +116,8 @@ TEST_F(LicenseTest, LicenseInfoOverride) {
|
|||||||
CheckLicenseValidity(false);
|
CheckLicenseValidity(false);
|
||||||
|
|
||||||
const std::string organization_name{"Memgraph"};
|
const std::string organization_name{"Memgraph"};
|
||||||
memgraph::utils::license::License license{
|
memgraph::license::License license{organization_name, 0, 0, memgraph::license::LicenseType::ENTERPRISE};
|
||||||
.organization_name = organization_name, .valid_until = 0, .memory_limit = 0};
|
const std::string license_key = memgraph::license::Encode(license);
|
||||||
const std::string license_key = memgraph::utils::license::Encode(license);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
SCOPED_TRACE("Checker should use overrides instead of info from the settings");
|
SCOPED_TRACE("Checker should use overrides instead of info from the settings");
|
||||||
@ -139,3 +138,40 @@ TEST_F(LicenseTest, LicenseInfoOverride) {
|
|||||||
CheckLicenseValidity(false);
|
CheckLicenseValidity(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(LicenseTest, LicenseType) {
|
||||||
|
CheckLicenseValidity(false);
|
||||||
|
const std::string organization_name{"Memgraph"};
|
||||||
|
{
|
||||||
|
memgraph::license::License license_entr{organization_name, 0, 0, memgraph::license::LicenseType::ENTERPRISE};
|
||||||
|
const std::string license_key = memgraph::license::Encode(license_entr);
|
||||||
|
license_checker->SetLicenseInfoOverride(license_key, organization_name);
|
||||||
|
CheckLicenseValidity(true);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
memgraph::license::License license_oem{organization_name, 0, 0, memgraph::license::LicenseType::OEM};
|
||||||
|
const std::string license_key = memgraph::license::Encode(license_oem);
|
||||||
|
license_checker->SetLicenseInfoOverride(license_key, organization_name);
|
||||||
|
CheckLicenseValidity(false);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
memgraph::license::License license_oem{organization_name, 0, 0, memgraph::license::LicenseType::OEM};
|
||||||
|
const std::string license_key = memgraph::license::Encode(license_oem);
|
||||||
|
license_checker->SetLicenseInfoOverride(license_key, organization_name);
|
||||||
|
CheckLicenseValidity(false);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
memgraph::license::License license_oem{organization_name, std::numeric_limits<int64_t>::min(),
|
||||||
|
std::numeric_limits<int64_t>::max(), memgraph::license::LicenseType::OEM};
|
||||||
|
const std::string license_key = memgraph::license::Encode(license_oem);
|
||||||
|
license_checker->SetLicenseInfoOverride(license_key, organization_name);
|
||||||
|
CheckLicenseValidity(false);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
memgraph::license::License license_oem{organization_name, std::numeric_limits<int64_t>::max(),
|
||||||
|
std::numeric_limits<int64_t>::min(), memgraph::license::LicenseType::OEM};
|
||||||
|
const std::string license_key = memgraph::license::Encode(license_oem);
|
||||||
|
license_checker->SetLicenseInfoOverride(license_key, organization_name);
|
||||||
|
CheckLicenseValidity(false);
|
||||||
|
}
|
||||||
|
}
|
@ -20,11 +20,11 @@
|
|||||||
#include "gmock/gmock.h"
|
#include "gmock/gmock.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
#include "license/license.hpp"
|
||||||
#include "query/context.hpp"
|
#include "query/context.hpp"
|
||||||
#include "query/exceptions.hpp"
|
#include "query/exceptions.hpp"
|
||||||
#include "query/interpret/frame.hpp"
|
#include "query/interpret/frame.hpp"
|
||||||
#include "query/plan/operator.hpp"
|
#include "query/plan/operator.hpp"
|
||||||
#include "utils/license.hpp"
|
|
||||||
|
|
||||||
#include "query_plan_common.hpp"
|
#include "query_plan_common.hpp"
|
||||||
#include "storage/v2/id_types.hpp"
|
#include "storage/v2/id_types.hpp"
|
||||||
@ -80,7 +80,7 @@ TEST(QueryPlan, CreateNodeWithAttributes) {
|
|||||||
|
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
TEST(QueryPlan, FineGrainedCreateNodeWithAttributes) {
|
TEST(QueryPlan, FineGrainedCreateNodeWithAttributes) {
|
||||||
memgraph::utils::license::global_license_checker.EnableTesting();
|
memgraph::license::global_license_checker.EnableTesting();
|
||||||
memgraph::query::AstStorage ast;
|
memgraph::query::AstStorage ast;
|
||||||
memgraph::query::SymbolTable symbol_table;
|
memgraph::query::SymbolTable symbol_table;
|
||||||
memgraph::storage::Storage db;
|
memgraph::storage::Storage db;
|
||||||
@ -164,7 +164,7 @@ TEST(QueryPlan, CreateReturn) {
|
|||||||
|
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
TEST(QueryPlan, FineGrainedCreateReturn) {
|
TEST(QueryPlan, FineGrainedCreateReturn) {
|
||||||
memgraph::utils::license::global_license_checker.EnableTesting();
|
memgraph::license::global_license_checker.EnableTesting();
|
||||||
|
|
||||||
// test CREATE (n:Person {age: 42}) RETURN n, n.age
|
// test CREATE (n:Person {age: 42}) RETURN n, n.age
|
||||||
memgraph::storage::Storage db;
|
memgraph::storage::Storage db;
|
||||||
@ -310,7 +310,7 @@ class CreateExpandWithAuthFixture : public testing::Test {
|
|||||||
AstStorage storage;
|
AstStorage storage;
|
||||||
SymbolTable symbol_table;
|
SymbolTable symbol_table;
|
||||||
|
|
||||||
void SetUp() override { memgraph::utils::license::global_license_checker.EnableTesting(); }
|
void SetUp() override { memgraph::license::global_license_checker.EnableTesting(); }
|
||||||
|
|
||||||
void ExecuteCreateExpand(bool cycle, memgraph::auth::User &user) {
|
void ExecuteCreateExpand(bool cycle, memgraph::auth::User &user) {
|
||||||
const auto label_node_1 = dba.NameToLabel("Node1");
|
const auto label_node_1 = dba.NameToLabel("Node1");
|
||||||
@ -470,7 +470,7 @@ class MatchCreateNodeWithAuthFixture : public testing::Test {
|
|||||||
AstStorage storage;
|
AstStorage storage;
|
||||||
SymbolTable symbol_table;
|
SymbolTable symbol_table;
|
||||||
|
|
||||||
void SetUp() override { memgraph::utils::license::global_license_checker.EnableTesting(); }
|
void SetUp() override { memgraph::license::global_license_checker.EnableTesting(); }
|
||||||
|
|
||||||
void InitGraph() {
|
void InitGraph() {
|
||||||
// add three nodes we'll match and expand-create from
|
// add three nodes we'll match and expand-create from
|
||||||
@ -600,7 +600,7 @@ class MatchCreateExpandWithAuthFixture : public testing::Test {
|
|||||||
AstStorage storage;
|
AstStorage storage;
|
||||||
SymbolTable symbol_table;
|
SymbolTable symbol_table;
|
||||||
|
|
||||||
void SetUp() override { memgraph::utils::license::global_license_checker.EnableTesting(); }
|
void SetUp() override { memgraph::license::global_license_checker.EnableTesting(); }
|
||||||
|
|
||||||
void InitGraph() {
|
void InitGraph() {
|
||||||
// add three nodes we'll match and expand-create from
|
// add three nodes we'll match and expand-create from
|
||||||
@ -818,7 +818,7 @@ class DeleteOperatorWithAuthFixture : public testing::Test {
|
|||||||
AstStorage storage;
|
AstStorage storage;
|
||||||
SymbolTable symbol_table;
|
SymbolTable symbol_table;
|
||||||
|
|
||||||
void SetUp() override { memgraph::utils::license::global_license_checker.EnableTesting(); }
|
void SetUp() override { memgraph::license::global_license_checker.EnableTesting(); }
|
||||||
|
|
||||||
void InitGraph() {
|
void InitGraph() {
|
||||||
std::vector<memgraph::query::VertexAccessor> vertices;
|
std::vector<memgraph::query::VertexAccessor> vertices;
|
||||||
@ -1253,7 +1253,7 @@ TEST(QueryPlan, SetLabels) {
|
|||||||
|
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
TEST(QueryPlan, SetLabelsWithFineGrained) {
|
TEST(QueryPlan, SetLabelsWithFineGrained) {
|
||||||
memgraph::utils::license::global_license_checker.EnableTesting();
|
memgraph::license::global_license_checker.EnableTesting();
|
||||||
auto set_labels = [&](memgraph::auth::User user, memgraph::query::DbAccessor dba,
|
auto set_labels = [&](memgraph::auth::User user, memgraph::query::DbAccessor dba,
|
||||||
std::vector<memgraph::storage::LabelId> labels) {
|
std::vector<memgraph::storage::LabelId> labels) {
|
||||||
ASSERT_TRUE(dba.InsertVertex().AddLabel(labels[0]).HasValue());
|
ASSERT_TRUE(dba.InsertVertex().AddLabel(labels[0]).HasValue());
|
||||||
@ -1426,7 +1426,7 @@ TEST(QueryPlan, RemoveLabels) {
|
|||||||
|
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
TEST(QueryPlan, RemoveLabelsFineGrainedFiltering) {
|
TEST(QueryPlan, RemoveLabelsFineGrainedFiltering) {
|
||||||
memgraph::utils::license::global_license_checker.EnableTesting();
|
memgraph::license::global_license_checker.EnableTesting();
|
||||||
auto remove_labels = [&](memgraph::auth::User user, memgraph::query::DbAccessor dba,
|
auto remove_labels = [&](memgraph::auth::User user, memgraph::query::DbAccessor dba,
|
||||||
std::vector<memgraph::storage::LabelId> labels) {
|
std::vector<memgraph::storage::LabelId> labels) {
|
||||||
auto v1 = dba.InsertVertex();
|
auto v1 = dba.InsertVertex();
|
||||||
@ -1896,7 +1896,7 @@ class UpdatePropertiesWithAuthFixture : public testing::Test {
|
|||||||
const memgraph::storage::PropertyId edge_prop{dba.NameToProperty(edge_prop_name)};
|
const memgraph::storage::PropertyId edge_prop{dba.NameToProperty(edge_prop_name)};
|
||||||
const memgraph::storage::PropertyValue edge_prop_value{1};
|
const memgraph::storage::PropertyValue edge_prop_value{1};
|
||||||
|
|
||||||
void SetUp() override { memgraph::utils::license::global_license_checker.EnableTesting(); }
|
void SetUp() override { memgraph::license::global_license_checker.EnableTesting(); }
|
||||||
|
|
||||||
void SetVertexProperty(memgraph::query::VertexAccessor vertex) {
|
void SetVertexProperty(memgraph::query::VertexAccessor vertex) {
|
||||||
static_cast<void>(vertex.SetProperty(entity_prop, entity_prop_value));
|
static_cast<void>(vertex.SetProperty(entity_prop, entity_prop_value));
|
||||||
|
@ -30,10 +30,10 @@
|
|||||||
#include "auth/auth.hpp"
|
#include "auth/auth.hpp"
|
||||||
#include "auth/models.hpp"
|
#include "auth/models.hpp"
|
||||||
#include "glue/auth_checker.hpp"
|
#include "glue/auth_checker.hpp"
|
||||||
|
#include "license/license.hpp"
|
||||||
#include "query/context.hpp"
|
#include "query/context.hpp"
|
||||||
#include "query/exceptions.hpp"
|
#include "query/exceptions.hpp"
|
||||||
#include "query/plan/operator.hpp"
|
#include "query/plan/operator.hpp"
|
||||||
#include "utils/license.hpp"
|
|
||||||
#include "utils/synchronized.hpp"
|
#include "utils/synchronized.hpp"
|
||||||
|
|
||||||
using namespace memgraph::query;
|
using namespace memgraph::query;
|
||||||
@ -50,7 +50,7 @@ class MatchReturnFixture : public testing::Test {
|
|||||||
void AddVertices(int count) {
|
void AddVertices(int count) {
|
||||||
for (int i = 0; i < count; i++) dba.InsertVertex();
|
for (int i = 0; i < count; i++) dba.InsertVertex();
|
||||||
}
|
}
|
||||||
void SetUp() override { memgraph::utils::license::global_license_checker.EnableTesting(); }
|
void SetUp() override { memgraph::license::global_license_checker.EnableTesting(); }
|
||||||
|
|
||||||
std::vector<Path> PathResults(std::shared_ptr<Produce> &op) {
|
std::vector<Path> PathResults(std::shared_ptr<Produce> &op) {
|
||||||
std::vector<Path> res;
|
std::vector<Path> res;
|
||||||
@ -485,7 +485,7 @@ class ExpandFixture : public testing::Test {
|
|||||||
ASSERT_TRUE(v1.AddLabel(dba.NameToLabel("l1")).HasValue());
|
ASSERT_TRUE(v1.AddLabel(dba.NameToLabel("l1")).HasValue());
|
||||||
ASSERT_TRUE(v2.AddLabel(dba.NameToLabel("l2")).HasValue());
|
ASSERT_TRUE(v2.AddLabel(dba.NameToLabel("l2")).HasValue());
|
||||||
ASSERT_TRUE(v3.AddLabel(dba.NameToLabel("l3")).HasValue());
|
ASSERT_TRUE(v3.AddLabel(dba.NameToLabel("l3")).HasValue());
|
||||||
memgraph::utils::license::global_license_checker.EnableTesting();
|
memgraph::license::global_license_checker.EnableTesting();
|
||||||
|
|
||||||
dba.AdvanceCommand();
|
dba.AdvanceCommand();
|
||||||
}
|
}
|
||||||
@ -628,7 +628,7 @@ class QueryPlanExpandVariable : public testing::Test {
|
|||||||
std::nullopt_t nullopt = std::nullopt;
|
std::nullopt_t nullopt = std::nullopt;
|
||||||
|
|
||||||
void SetUp() {
|
void SetUp() {
|
||||||
memgraph::utils::license::global_license_checker.EnableTesting();
|
memgraph::license::global_license_checker.EnableTesting();
|
||||||
|
|
||||||
// create the graph
|
// create the graph
|
||||||
int chain_length = 3;
|
int chain_length = 3;
|
||||||
@ -1778,7 +1778,7 @@ class QueryPlanExpandWeightedShortestPath : public testing::Test {
|
|||||||
Symbol total_weight = symbol_table.CreateSymbol("total_weight", true);
|
Symbol total_weight = symbol_table.CreateSymbol("total_weight", true);
|
||||||
|
|
||||||
void SetUp() {
|
void SetUp() {
|
||||||
memgraph::utils::license::global_license_checker.EnableTesting();
|
memgraph::license::global_license_checker.EnableTesting();
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
v.push_back(dba.InsertVertex());
|
v.push_back(dba.InsertVertex());
|
||||||
@ -2208,7 +2208,7 @@ class QueryPlanExpandAllShortestPaths : public testing::Test {
|
|||||||
Symbol total_weight = symbol_table.CreateSymbol("total_weight", true);
|
Symbol total_weight = symbol_table.CreateSymbol("total_weight", true);
|
||||||
|
|
||||||
void SetUp() {
|
void SetUp() {
|
||||||
memgraph::utils::license::global_license_checker.EnableTesting();
|
memgraph::license::global_license_checker.EnableTesting();
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
v.push_back(dba.InsertVertex());
|
v.push_back(dba.InsertVertex());
|
||||||
|
@ -13,11 +13,11 @@
|
|||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include "license/license.hpp"
|
||||||
#include "query/frontend/ast/ast.hpp"
|
#include "query/frontend/ast/ast.hpp"
|
||||||
#include "query/frontend/ast/ast_visitor.hpp"
|
#include "query/frontend/ast/ast_visitor.hpp"
|
||||||
#include "query/frontend/semantic/required_privileges.hpp"
|
#include "query/frontend/semantic/required_privileges.hpp"
|
||||||
#include "storage/v2/id_types.hpp"
|
#include "storage/v2/id_types.hpp"
|
||||||
#include "utils/license.hpp"
|
|
||||||
|
|
||||||
#include "query_common.hpp"
|
#include "query_common.hpp"
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ TEST_F(TestPrivilegeExtractor, CreateIndex) {
|
|||||||
}
|
}
|
||||||
#ifdef MG_ENTERPRISE
|
#ifdef MG_ENTERPRISE
|
||||||
TEST_F(TestPrivilegeExtractor, AuthQuery) {
|
TEST_F(TestPrivilegeExtractor, AuthQuery) {
|
||||||
memgraph::utils::license::global_license_checker.EnableTesting();
|
memgraph::license::global_license_checker.EnableTesting();
|
||||||
auto label_privileges = std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>>{};
|
auto label_privileges = std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>>{};
|
||||||
auto edge_type_privileges =
|
auto edge_type_privileges =
|
||||||
std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>>{};
|
std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>>{};
|
||||||
|
Loading…
Reference in New Issue
Block a user