1
#include "source/common/version/version.h"
2

            
3
#include <map>
4
#include <regex>
5
#include <string>
6

            
7
#include "source/common/common/fmt.h"
8
#include "source/common/common/macros.h"
9
#include "source/common/protobuf/utility.h"
10

            
11
#include "absl/strings/numbers.h"
12
#include "absl/strings/str_split.h"
13
#include "absl/strings/string_view.h"
14
#include "openssl/crypto.h"
15

            
16
extern const char build_scm_revision[];
17
extern const char build_scm_status[];
18
extern const char build_version_suffix[];
19

            
20
namespace Envoy {
21
12813
const std::string& VersionInfo::revision() {
22
12813
  CONSTRUCT_ON_FIRST_USE(std::string, build_scm_revision);
23
12813
}
24

            
25
2144
const std::string& VersionInfo::revisionStatus() {
26
2144
  CONSTRUCT_ON_FIRST_USE(std::string, build_scm_status);
27
2144
}
28

            
29
3625
const std::string& VersionInfo::version() {
30
3625
  CONSTRUCT_ON_FIRST_USE(std::string, fmt::format("{}/{}{}/{}/{}/{}", revision(),
31
3625
                                                  BUILD_VERSION_NUMBER, build_version_suffix,
32
3625
                                                  revisionStatus(), buildType(), sslVersion()));
33
3625
}
34

            
35
10724
const envoy::config::core::v3::BuildVersion& VersionInfo::buildVersion() {
36
10724
  static const auto* result = new envoy::config::core::v3::BuildVersion(
37
10724
      makeBuildVersion(fmt::format("{}{}", BUILD_VERSION_NUMBER, build_version_suffix).c_str()));
38
10724
  return *result;
39
10724
}
40

            
41
10675
bool VersionInfo::sslFipsCompliant() { return FIPS_mode() == 1; }
42

            
43
2144
const std::string& VersionInfo::buildType() {
44
2144
#ifdef NDEBUG
45
2144
  static const std::string release_type = "RELEASE";
46
#else
47
  static const std::string release_type = "DEBUG";
48
#endif
49
2144
  return release_type;
50
2144
}
51

            
52
2144
const std::string& VersionInfo::sslVersion() {
53
2144
#ifdef ENVOY_SSL_VERSION
54
2144
  static const std::string ssl_version = ENVOY_SSL_VERSION;
55
#else
56
  static const std::string ssl_version = "no-ssl";
57
#endif
58
2144
  return ssl_version;
59
2144
}
60

            
61
472
envoy::config::core::v3::BuildVersion VersionInfo::makeBuildVersion(const char* version) {
62
472
  envoy::config::core::v3::BuildVersion result;
63
  // Split BUILD_VERSION_NUMBER into version and an optional build label after the '-'
64
472
  std::regex ver_regex("([\\d]+)\\.([\\d]+)\\.([\\d]+)(-(.*))?");
65
  // Match indexes, given the regex above
66
472
  constexpr std::cmatch::size_type major = 1;
67
472
  constexpr std::cmatch::size_type minor = 2;
68
472
  constexpr std::cmatch::size_type patch = 3;
69
472
  constexpr std::cmatch::size_type label = 5;
70
472
  std::cmatch match;
71
472
  if (std::regex_match(version, match, ver_regex)) {
72
471
    int value = 0;
73
471
    if (absl::SimpleAtoi(match.str(major), &value)) {
74
471
      result.mutable_version()->set_major_number(value);
75
471
    }
76
471
    if (absl::SimpleAtoi(match.str(minor), &value)) {
77
471
      result.mutable_version()->set_minor_number(value);
78
471
    }
79
471
    if (absl::SimpleAtoi(match.str(patch), &value)) {
80
471
      result.mutable_version()->set_patch(value);
81
471
    }
82
471
  }
83
472
  std::map<std::string, std::string> fields;
84
472
  if (!match.str(label).empty()) {
85
470
    fields[BuildVersionMetadataKeys::get().BuildLabel] = match.str(label);
86
470
  }
87
472
  fields[BuildVersionMetadataKeys::get().BuildType] = buildType();
88
472
  fields[BuildVersionMetadataKeys::get().SslVersion] = sslVersion();
89
472
  fields[BuildVersionMetadataKeys::get().RevisionSHA] = revision();
90
472
  fields[BuildVersionMetadataKeys::get().RevisionStatus] = revisionStatus();
91
472
  *result.mutable_metadata() = MessageUtil::keyValueStruct(fields);
92
472
  return result;
93
472
}
94

            
95
} // namespace Envoy