mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 08:58:41 +00:00
chore: merge main
This commit is contained in:
commit
e3e7b6a115
43 changed files with 292 additions and 128 deletions
2
.github/workflows/fleet-and-orbit.yml
vendored
2
.github/workflows/fleet-and-orbit.yml
vendored
|
|
@ -63,7 +63,7 @@ jobs:
|
|||
strategy:
|
||||
matrix:
|
||||
go-version: ["${{ vars.GO_VERSION }}"]
|
||||
mysql: ["mysql:5.7"]
|
||||
mysql: ["mysql:8.0.36"]
|
||||
runs-on: ubuntu-latest
|
||||
needs: gen
|
||||
steps:
|
||||
|
|
|
|||
2
.github/workflows/test-go.yaml
vendored
2
.github/workflows/test-go.yaml
vendored
|
|
@ -45,7 +45,7 @@ jobs:
|
|||
suite: ["integration", "core"]
|
||||
os: [ubuntu-latest]
|
||||
go-version: ['${{ vars.GO_VERSION }}']
|
||||
mysql: ["mysql:5.7.21", "mysql:8.0.28"]
|
||||
mysql: ["mysql:8.0.36"]
|
||||
continue-on-error: ${{ matrix.suite == 'integration' }} # Since integration tests have a higher chance of failing, often for unrelated reasons, we don't want to fail the whole job if they fail
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,14 +69,14 @@ echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docke
|
|||
apt update
|
||||
apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
|
||||
|
||||
docker pull mysql@sha256:16e159331007eccc069822f7b731272043ed572a79a196a05ffa2ea127caaf67 # mysql:5.7.38 as of 2022/05/19
|
||||
docker pull mysql@sha256:134e2d1c7c517d05e5328a77aa5a165a314dc4c4116503e7e089494f4e398ab1 # mysql:8.0.36 as of 2024/07/04
|
||||
|
||||
######################
|
||||
# MySQL (dockerized) #
|
||||
######################
|
||||
|
||||
# mysql:5.7.38 as of 2022/05/19
|
||||
docker pull mysql@sha256:16e159331007eccc069822f7b731272043ed572a79a196a05ffa2ea127caaf67
|
||||
# mysql:8.0.36 as of 2024/07/04
|
||||
docker pull mysql@sha256:134e2d1c7c517d05e5328a77aa5a165a314dc4c4116503e7e089494f4e398ab1
|
||||
|
||||
# Create the Fleet MySQL data folder
|
||||
mkdir -p /etc/fleet
|
||||
|
|
@ -102,14 +102,14 @@ Restart=always
|
|||
|
||||
ExecStartPre=-/usr/bin/docker exec %n stop
|
||||
ExecStartPre=-/usr/bin/docker rm %n
|
||||
ExecStartPre=-/usr/bin/docker pull mysql@sha256:16e159331007eccc069822f7b731272043ed572a79a196a05ffa2ea127caaf67
|
||||
ExecStartPre=-/usr/bin/docker pull mysql@sha256:134e2d1c7c517d05e5328a77aa5a165a314dc4c4116503e7e089494f4e398ab1
|
||||
|
||||
ExecStart=/usr/bin/docker run --rm \
|
||||
--name %n \
|
||||
-p 127.0.0.1:3306:3306 \
|
||||
-v /etc/fleet/mysql:/var/lib/mysql \
|
||||
--env-file /etc/fleet/mysql.env \
|
||||
mysql@sha256:16e159331007eccc069822f7b731272043ed572a79a196a05ffa2ea127caaf67
|
||||
mysql@sha256:134e2d1c7c517d05e5328a77aa5a165a314dc4c4116503e7e089494f4e398ab1
|
||||
|
||||
ExecStop=/usr/bin/docker stop %n
|
||||
|
||||
|
|
@ -435,7 +435,7 @@ To run MySQL, we’ll have to do the following:
|
|||
We can pull the [official MySQL docker image](https://hub.docker.com/_/mysql) like so:
|
||||
|
||||
```sh
|
||||
$ docker pull mysql@sha256:16e159331007eccc069822f7b731272043ed572a79a196a05ffa2ea127caaf67 # mysql:5.7.38 as of 2022/05/19
|
||||
$ docker pull mysql@sha256:134e2d1c7c517d05e5328a77aa5a165a314dc4c4116503e7e089494f4e398ab1 # mysql:8.0.36 as of 2024/07/04
|
||||
```
|
||||
|
||||
### Create & enable a systemd unit for MySQL
|
||||
|
|
@ -472,14 +472,14 @@ Restart=always
|
|||
|
||||
ExecStartPre=-/usr/bin/docker exec %n stop
|
||||
ExecStartPre=-/usr/bin/docker rm %n
|
||||
ExecStartPre=-/usr/bin/docker pull mysql@sha256:16e159331007eccc069822f7b731272043ed572a79a196a05ffa2ea127caaf67
|
||||
ExecStartPre=-/usr/bin/docker pull mysql@sha256:134e2d1c7c517d05e5328a77aa5a165a314dc4c4116503e7e089494f4e398ab1
|
||||
|
||||
ExecStart=/usr/bin/docker run --rm \
|
||||
--name %n \
|
||||
-p 127.0.0.1:3306:3306 \
|
||||
-v /etc/fleet/mysql:/var/lib/mysql \
|
||||
--env-file /etc/fleet/mysql.env \
|
||||
mysql@sha256:16e159331007eccc069822f7b731272043ed572a79a196a05ffa2ea127caaf67
|
||||
mysql@sha256:134e2d1c7c517d05e5328a77aa5a165a314dc4c4116503e7e089494f4e398ab1
|
||||
|
||||
ExecStop=/usr/bin/docker stop %n
|
||||
|
||||
|
|
@ -712,4 +712,4 @@ Now that you’re ready to use Fleet and have a host installed. Here's some next
|
|||
<meta name="publishedOn" value="2022-06-27">
|
||||
<meta name="category" value="guides">
|
||||
<meta name="articleImageUrl" value="../website/assets/images/articles/deploy-fleet-on-hetzner-cloud-800x450@2x.png">
|
||||
<meta name="description" value="Learn how to deploy Fleet on Hetzner Cloud using cloud-init and Docker.">
|
||||
<meta name="description" value="Learn how to deploy Fleet on Hetzner Cloud using cloud-init and Docker.">
|
||||
|
|
|
|||
2
changes/17249-mysql-8
Normal file
2
changes/17249-mysql-8
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
* Drop support for MySQL 5.7
|
||||
* Minimum requirements raised to MySQL 8.0
|
||||
|
|
@ -0,0 +1 @@
|
|||
* Fixed a bug that set `last_enrolled_at` during orbit re-enrollment, which caused osquery enroll failures when `FLEET_OSQUERY_ENROLL_COOLDOWN` is set .
|
||||
2
changes/20618-nil-tz-not-handled
Normal file
2
changes/20618-nil-tz-not-handled
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
* Fix a bug where Fleet google calendar events generated by Fleet <= 4.53.0 were not correctly
|
||||
processed by 4.54.0
|
||||
|
|
@ -5,7 +5,7 @@ services:
|
|||
# officially supported).
|
||||
# To run in macOS M1, set FLEET_MYSQL_IMAGE=arm64v8/mysql:oracle FLEET_MYSQL_PLATFORM=linux/arm64/v8
|
||||
mysql:
|
||||
image: ${FLEET_MYSQL_IMAGE:-mysql:5.7.21}
|
||||
image: ${FLEET_MYSQL_IMAGE:-mysql:8.0.36}
|
||||
platform: ${FLEET_MYSQL_PLATFORM:-linux/x86_64}
|
||||
volumes:
|
||||
- mysql-persistent-volume:/tmp
|
||||
|
|
@ -30,7 +30,7 @@ services:
|
|||
- "3306:3306"
|
||||
|
||||
mysql_test:
|
||||
image: ${FLEET_MYSQL_IMAGE:-mysql:5.7.21}
|
||||
image: ${FLEET_MYSQL_IMAGE:-mysql:8.0.36}
|
||||
platform: ${FLEET_MYSQL_PLATFORM:-linux/x86_64}
|
||||
# innodb-file-per-table=OFF gives ~20% speedup for test runs.
|
||||
command: [
|
||||
|
|
@ -56,7 +56,7 @@ services:
|
|||
- /tmpfs
|
||||
|
||||
mysql_replica_test:
|
||||
image: ${FLEET_MYSQL_IMAGE:-mysql:5.7.21}
|
||||
image: ${FLEET_MYSQL_IMAGE:-mysql:8.0.36}
|
||||
platform: ${FLEET_MYSQL_PLATFORM:-linux/x86_64}
|
||||
# innodb-file-per-table=OFF gives ~20% speedup for test runs.
|
||||
command: [
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ The maximum amount of time, in seconds, a connection may be reused.
|
|||
|
||||
##### mysql_sql_mode
|
||||
|
||||
Sets the connection `sql_mode`. See [MySQL Reference](https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html) for more details.
|
||||
Sets the connection `sql_mode`. See [MySQL Reference](https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html) for more details.
|
||||
This setting should not usually be used.
|
||||
|
||||
- Default value: `""`
|
||||
|
|
@ -2247,7 +2247,7 @@ The IAM identity used in this context must be allowed to perform the following a
|
|||
AWS secret access key to use for S3 authentication.
|
||||
|
||||
- Default value: none
|
||||
- Environment variable: `FLEET_S3_SECRET_ACCESS_KEY`
|
||||
- Environment variable: `FLEET_S3_SOFTWARE_INSTALLERS_SECRET_ACCESS_KEY`
|
||||
- Config file format:
|
||||
```yaml
|
||||
s3:
|
||||
|
|
|
|||
|
|
@ -23,8 +23,7 @@ The default flagfile provided in the "Add new host" dialog also includes this co
|
|||
The `carver_block_size` flag should be configured in osquery.
|
||||
|
||||
For the (default) MySQL Backend, the configured value must be less than the value of
|
||||
`max_allowed_packet` in the MySQL connection, allowing for some overhead. The default for [MySQL 5.7](https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_max_allowed_packet)
|
||||
is 4MB and for [MySQL 8](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_max_allowed_packet) it is 64MB.
|
||||
`max_allowed_packet` in the MySQL connection, allowing for some overhead. The default for [MySQL 8](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_max_allowed_packet) it is 64MB.
|
||||
|
||||
For the S3/Minio backend, this value must be set to at least 5MiB (`5242880`) due to the
|
||||
[constraints of S3's multipart
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ Fleet currently has three infrastructure dependencies: MySQL, Redis, and a TLS c
|
|||
Fleet uses MySQL extensively as its main database. Many cloud providers (such as [AWS](https://aws.amazon.com/rds/mysql/) and [GCP](https://cloud.google.com/sql/)) host reliable MySQL services which you may consider for this purpose. A well-supported MySQL [Docker image](https://hub.docker.com/_/mysql/) also exists if you would rather run MySQL in a container.
|
||||
For more information on how to configure the `fleet` binary to use the correct MySQL instance, see the [Configuration](https://fleetdm.com/docs/deploying/configuration) document.
|
||||
|
||||
Fleet requires at least MySQL version 5.7, and is tested using the InnoDB storage engine.
|
||||
Fleet requires at least MySQL version 8.0, and is tested using the InnoDB storage engine.
|
||||
|
||||
There are many "drop-in replacements" for MySQL available. If you'd like to experiment with some bleeding-edge technology and use Fleet with one of these alternative database servers, we think that's awesome! Please be aware they are not officially supported and that it is very important to set up a dev environment to thoroughly test new releases.
|
||||
|
||||
|
|
@ -277,7 +277,7 @@ The following permissions are the minimum required to apply AWS terraform resour
|
|||
GCP reference architecture can be found in [the Fleet repository](https://github.com/fleetdm/fleet/tree/main/infrastructure/dogfood/terraform/gcp). This configuration includes:
|
||||
|
||||
- Cloud Run (Fleet backend)
|
||||
- Cloud SQL MySQL 5.7 (Fleet database)
|
||||
- Cloud SQL MySQL 8.0 (Fleet database)
|
||||
- Memorystore Redis (Fleet cache & live query orchestrator)
|
||||
|
||||
GCP support for add/install software and file carve features is coming soon. Get [commmunity support](https://chat.osquery.io/c/fleet).
|
||||
|
|
|
|||
|
|
@ -594,7 +594,7 @@ This could be caused by a mismatched connection limit between the Fleet server a
|
|||
|
||||
### Why am I receiving a database connection error when attempting to "prepare" the database?
|
||||
|
||||
First, check if you have a version of MySQL installed that is at least 5.7. Then, make sure that you currently have a MySQL server running.
|
||||
First, check if you have a version of MySQL installed that is at least 8.0. Then, make sure that you currently have a MySQL server running.
|
||||
|
||||
The next step is to make sure the credentials for the database match what is expected. Test your ability to connect to the database with `mysql -u<username> -h<hostname_or_ip> -P<port> -D<database_name> -p`.
|
||||
|
||||
|
|
@ -614,7 +614,7 @@ Yes! Please sign up for the [Fleet Cloud Beta](https://kqphpqst851.typeform.com/
|
|||
|
||||
### What MySQL versions are supported?
|
||||
|
||||
Fleet is tested with MySQL 5.7.21 and 8.0.28. Newer versions of MySQL 5.7 and MySQL 8 typically work well. AWS Aurora requires at least version 2.10.0. Please avoid using MariaDB or other MySQL variants that are not officially supported. Compatibility issues have been identified with MySQL variants, and these may not be addressed in future Fleet releases.
|
||||
Fleet is tested with MySQL 8.0.36. Newer versions of MySQL 8 typically work well. AWS Aurora requires at least version 2.10.0. Please avoid using MariaDB or other MySQL variants that are not officially supported. Compatibility issues have been identified with MySQL variants, and these may not be addressed in future Fleet releases.
|
||||
|
||||
### What are the MySQL user requirements?
|
||||
|
||||
|
|
@ -677,7 +677,7 @@ If you would like to use Fleet's MDM features, the following endpoints need to b
|
|||
|
||||
### What is the minimum version of MySQL required by Fleet?
|
||||
|
||||
Fleet requires at least MySQL version 5.7.
|
||||
Fleet requires at least MySQL version 8.0.
|
||||
|
||||
### How do I migrate from Fleet Free to Fleet Premium?
|
||||
|
||||
|
|
|
|||
|
|
@ -92,10 +92,9 @@ GitOps is an API-only and write-only role that can be used on CI/CD pipelines.
|
|||
| View all [MDM settings](https://fleetdm.com/docs/using-fleet/mdm-macos-settings) | | | | ✅ | ✅ |
|
||||
| Edit setup experience (end user authentication, bootstrap package, Setup Assistant)\* | | | ✅ | ✅ | ✅ |
|
||||
| Edit end user license agreement (EULA)\* | | | | ✅ | |
|
||||
| Run arbitrary scripts on hosts | | | ✅ | ✅ | |
|
||||
| View saved scripts | ✅ | ✅ | ✅ | ✅ | |
|
||||
| Edit/upload saved scripts | | | ✅ | ✅ | ✅ |
|
||||
| Run saved scripts on hosts | ✅ | ✅ | ✅ | ✅ | |
|
||||
| Run scripts on hosts | | | ✅ | ✅ | |
|
||||
| View saved scripts\* | ✅ | ✅ | ✅ | ✅ | |
|
||||
| Edit/upload saved scripts\* | | | ✅ | ✅ | ✅ |
|
||||
| Lock, unlock, and wipe hosts\* | | | ✅ | ✅ | |
|
||||
|
||||
\* Applies only to Fleet Premium
|
||||
|
|
@ -165,10 +164,9 @@ Users with access to multiple teams can be assigned different roles for each tea
|
|||
| View metadata of MDM macOS bootstrap packages | | | ✅ | ✅ | |
|
||||
| Edit/upload MDM macOS bootstrap packages | | | ✅ | ✅ | ✅ |
|
||||
| Enable/disable MDM macOS setup end user authentication | | | ✅ | ✅ | ✅ |
|
||||
| Run arbitrary scripts on hosts | | | ✅ | ✅ | |
|
||||
| Run scripts on hosts | | | ✅ | ✅ | |
|
||||
| View saved scripts | ✅ | ✅ | ✅ | ✅ | |
|
||||
| Edit/upload saved scripts | | | ✅ | ✅ | |
|
||||
| Run saved scripts on hosts | ✅ | ✅ | ✅ | ✅ | |
|
||||
| View script details by host | ✅ | ✅ | ✅ | ✅ | |
|
||||
| Lock, unlock, and wipe hosts | | | ✅ | ✅ | |
|
||||
|
||||
|
|
|
|||
|
|
@ -280,7 +280,9 @@ func (c *GoogleCalendar) GetAndUpdateEvent(event *fleet.CalendarEvent, genBodyFn
|
|||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
tzUpdated := c.location.String() != event.TimeZone
|
||||
latestTzName := c.location.String()
|
||||
// nil if cal event created before Fleet tracked timezone
|
||||
tzUpdated := event.TimeZone == nil || (latestTzName != *event.TimeZone)
|
||||
|
||||
gEvent, err := c.config.API.GetEvent(details.ID, details.ETag)
|
||||
|
||||
|
|
@ -291,7 +293,7 @@ func (c *GoogleCalendar) GetAndUpdateEvent(event *fleet.CalendarEvent, genBodyFn
|
|||
if tzUpdated {
|
||||
// this condition occurs when the event itself hasn't been updated, but the calendar timezone
|
||||
// has been, so update the Fleet event's timezone
|
||||
event.TimeZone = c.location.String()
|
||||
event.TimeZone = &latestTzName
|
||||
return event, true, nil
|
||||
}
|
||||
return event, false, nil
|
||||
|
|
@ -307,7 +309,7 @@ func (c *GoogleCalendar) GetAndUpdateEvent(event *fleet.CalendarEvent, genBodyFn
|
|||
if tzUpdated {
|
||||
// this condition occurs when the event itself hasn't been updated, but the calendar timezone
|
||||
// has been, so just update the event's timezone
|
||||
event.TimeZone = c.location.String()
|
||||
event.TimeZone = &latestTzName
|
||||
return event, true, nil
|
||||
}
|
||||
return event, false, nil
|
||||
|
|
@ -642,12 +644,12 @@ func (c *GoogleCalendar) googleEventToFleetEvent(startTime time.Time, endTime ti
|
|||
resourceID string) (
|
||||
*fleet.CalendarEvent, error,
|
||||
) {
|
||||
|
||||
tzName := c.location.String()
|
||||
fleetEvent := &fleet.CalendarEvent{}
|
||||
fleetEvent.StartTime = startTime
|
||||
fleetEvent.EndTime = endTime
|
||||
fleetEvent.Email = c.currentUserEmail
|
||||
fleetEvent.TimeZone = c.location.String()
|
||||
fleetEvent.TimeZone = &tzName
|
||||
fleetEvent.UUID = eventUUID
|
||||
details := &eventDetails{
|
||||
ID: event.Id,
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ func TestGoogleCalendar_GetAndUpdateEvent(t *testing.T) {
|
|||
const baseETag = "event-eTag"
|
||||
const baseEventID = "event-id"
|
||||
const baseResourceID = "resource-id"
|
||||
const baseTzName = "America/New_York"
|
||||
baseTzName := "America/New_York"
|
||||
baseTzLocation, _ := time.LoadLocation(baseTzName)
|
||||
mockAPI.GetEventFunc = func(id, eTag string) (*calendar.Event, error) {
|
||||
assert.Equal(t, baseEventID, id)
|
||||
|
|
@ -228,7 +228,7 @@ func TestGoogleCalendar_GetAndUpdateEvent(t *testing.T) {
|
|||
StartTime: eventStartTime,
|
||||
EndTime: time.Now().Add(time.Hour).In(baseTzLocation),
|
||||
Data: []byte(`{"ID":"` + baseEventID + `","ETag":"` + baseETag + `"}`),
|
||||
TimeZone: baseTzName,
|
||||
TimeZone: &baseTzName,
|
||||
}
|
||||
|
||||
// ETag matches
|
||||
|
|
@ -525,7 +525,7 @@ func TestGoogleCalendar_CreateEvent(t *testing.T) {
|
|||
assert.Equal(t, baseEventID, details.ID)
|
||||
assert.Equal(t, channelUUID, details.ChannelID)
|
||||
assert.Equal(t, baseResourceID, details.ResourceID)
|
||||
assert.Equal(t, tzId, event.TimeZone)
|
||||
assert.Equal(t, tzId, *event.TimeZone)
|
||||
|
||||
// Workday already ended
|
||||
date = time.Now().Add(-48 * time.Hour)
|
||||
|
|
|
|||
|
|
@ -28,16 +28,6 @@
|
|||
autoIssue:
|
||||
labels: [ "#g-digital-experience" ]
|
||||
repo: fleet
|
||||
-
|
||||
task: "Generate latest schema"
|
||||
startedOn: "2024-02-19"
|
||||
frequency: "Weekly"
|
||||
description: "After each sprint, generate the latest tables json file to incorporate any new schema documentation."
|
||||
moreInfoUrl: https://fleetdm.com/handbook/company/product-groups#changes-to-tables-schema
|
||||
dri: "eashaw"
|
||||
autoIssue:
|
||||
labels: [ "#g-digital-experience" ]
|
||||
repo: fleet
|
||||
-
|
||||
task: "Check osquery Slack invitation"
|
||||
startedOn: "2023-11-10"
|
||||
|
|
|
|||
82
infrastructure/dogfood/terraform/gcp/.terraform.lock.hcl
Normal file
82
infrastructure/dogfood/terraform/gcp/.terraform.lock.hcl
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
# This file is maintained automatically by "terraform init".
|
||||
# Manual edits may be lost in future updates.
|
||||
|
||||
provider "registry.terraform.io/hashicorp/google" {
|
||||
version = "4.51.0"
|
||||
constraints = ">= 2.12.0, >= 3.45.0, >= 3.53.0, >= 3.60.0, >= 4.51.0, 4.51.0, < 5.0.0, < 6.0.0"
|
||||
hashes = [
|
||||
"h1:7JFdiV9bvV6R+AeWzvNbVeoega481sJY3PqtIbrwTsM=",
|
||||
"zh:001bf7478e495d497ffd4054453c97ab4dd3e6a24d46496d51d4c8094e95b2b1",
|
||||
"zh:19db72113552dd295854a99840e85678d421312708e8329a35787fff1baeed8b",
|
||||
"zh:42c3e629ace225a2cb6cf87b8fabeaf1c56ac8eca6a77b9e3fc489f3cc0a9db5",
|
||||
"zh:50b930755c4b1f8a01c430d8f688ea79de0b0198c87511baa3a783e360d7e624",
|
||||
"zh:5acd67f0aafff5ad59e179543cccd1ffd48d69b98af0228506403b8d8193b340",
|
||||
"zh:70128d57b4b4bf07df941172e6af15c4eda8396af5cc2b0128c906983c7b7fad",
|
||||
"zh:7905fac0ba2becf0e97edfcd4224e57466b04f960f36a3ec654a0a3c2ffececb",
|
||||
"zh:79b4cc760305cd77c1ff841f789184f808b8052e8f4faa5cb8d518e4c13beb22",
|
||||
"zh:c7aebd7d7dd2b29de28e382500d36fae8b4d8a192cf05e41ea29c66f1251acfc",
|
||||
"zh:d8b4494b13ef5af65d3afedf05bf7565918f1e31ad68ae0df81f5c3b12baf519",
|
||||
"zh:e6e68ef6881bc3312db50c9fd761f226f34d7834b64f90d96616b7ca6b1daf34",
|
||||
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
|
||||
]
|
||||
}
|
||||
|
||||
provider "registry.terraform.io/hashicorp/google-beta" {
|
||||
version = "4.85.0"
|
||||
constraints = ">= 3.45.0, >= 3.53.0, >= 3.62.0, < 5.0.0, < 6.0.0"
|
||||
hashes = [
|
||||
"h1:YkCDGkP0AUZoNobLoxRnM52Pi4alYE9EFXalEu8p8E8=",
|
||||
"zh:40e9c7ec46955b4d79065a14185043a4ad6af8d0246715853fc5c99208b66980",
|
||||
"zh:5950a9ba2f96420ea5335b543e315b1a47a705f9a9abfc53c6fec52d084eddcb",
|
||||
"zh:5dfa98d32246a5d97e018f2b91b0e921cc6f061bc8591884f3b144f0d62f1c20",
|
||||
"zh:628d0ca35c6d4c35077859bb0a5534c1de44f23a91e190f9c3f06f2358172e75",
|
||||
"zh:6e78d54fd4de4151968149b4c3521f563a8b5c55aad423dba5968a9114b65ae4",
|
||||
"zh:91c3bc443188638353285bd35b06d3a3b39b42b3b4cc0637599a430438fba2f7",
|
||||
"zh:9e91b03363ebf39eea5ec0fbe7675f6979883aa9ad9a36664357d8513a007cf3",
|
||||
"zh:db9a8d6bfe075fb38c260986ab557d40e8d18e5698c62956a6da8120fae01d59",
|
||||
"zh:e41169c49f3bb53217905509e2ba8bb4680c373e1f54db7fac1b7f72943a1004",
|
||||
"zh:f32f55a8af605afbc940814e17493ac83d9d66cd6da9bbc247e0a833a0aa37ec",
|
||||
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
|
||||
"zh:f6561a6badc3af842f9ad5bb926104954047f07cb90fadcca1357441cc67d91d",
|
||||
]
|
||||
}
|
||||
|
||||
provider "registry.terraform.io/hashicorp/null" {
|
||||
version = "3.1.1"
|
||||
constraints = "~> 3.1.0"
|
||||
hashes = [
|
||||
"h1:71sNUDvmiJcijsvfXpiLCz0lXIBSsEJjMxljt7hxMhw=",
|
||||
"zh:063466f41f1d9fd0dd93722840c1314f046d8760b1812fa67c34de0afcba5597",
|
||||
"zh:08c058e367de6debdad35fc24d97131c7cf75103baec8279aba3506a08b53faf",
|
||||
"zh:73ce6dff935150d6ddc6ac4a10071e02647d10175c173cfe5dca81f3d13d8afe",
|
||||
"zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
|
||||
"zh:8fdd792a626413502e68c195f2097352bdc6a0df694f7df350ed784741eb587e",
|
||||
"zh:976bbaf268cb497400fd5b3c774d218f3933271864345f18deebe4dcbfcd6afa",
|
||||
"zh:b21b78ca581f98f4cdb7a366b03ae9db23a73dfa7df12c533d7c19b68e9e72e5",
|
||||
"zh:b7fc0c1615dbdb1d6fd4abb9c7dc7da286631f7ca2299fb9cd4664258ccfbff4",
|
||||
"zh:d1efc942b2c44345e0c29bc976594cb7278c38cfb8897b344669eafbc3cddf46",
|
||||
"zh:e356c245b3cd9d4789bab010893566acace682d7db877e52d40fc4ca34a50924",
|
||||
"zh:ea98802ba92fcfa8cf12cbce2e9e7ebe999afbf8ed47fa45fc847a098d89468b",
|
||||
"zh:eff8872458806499889f6927b5d954560f3d74bf20b6043409edf94d26cd906f",
|
||||
]
|
||||
}
|
||||
|
||||
provider "registry.terraform.io/hashicorp/random" {
|
||||
version = "3.1.3"
|
||||
constraints = "~> 3.1.0"
|
||||
hashes = [
|
||||
"h1:nLWniS8xhb32qRQy+n4bDPjQ7YWZPVMR3v1vSrx7QyY=",
|
||||
"zh:26e07aa32e403303fc212a4367b4d67188ac965c37a9812e07acee1470687a73",
|
||||
"zh:27386f48e9c9d849fbb5a8828d461fde35e71f6b6c9fc235bc4ae8403eb9c92d",
|
||||
"zh:5f4edda4c94240297bbd9b83618fd362348cadf6bf24ea65ea0e1844d7ccedc0",
|
||||
"zh:646313a907126cd5e69f6a9fafe816e9154fccdc04541e06fed02bb3a8fa2d2e",
|
||||
"zh:7349692932a5d462f8dee1500ab60401594dddb94e9aa6bf6c4c0bd53e91bbb8",
|
||||
"zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
|
||||
"zh:9034daba8d9b32b35930d168f363af04cecb153d5849a7e4a5966c97c5dc956e",
|
||||
"zh:bb81dfca59ef5f949ef39f19ea4f4de25479907abc28cdaa36d12ecd7c0a9699",
|
||||
"zh:bcf7806b99b4c248439ae02c8e21f77aff9fadbc019ce619b929eef09d1221bb",
|
||||
"zh:d708e14d169e61f326535dd08eecd3811cd4942555a6f8efabc37dbff9c6fc61",
|
||||
"zh:dc294e19a46e1cefb9e557a7b789c8dd8f319beca99b8c265181bc633dc434cc",
|
||||
"zh:f9d758ee53c55dc016dd736427b6b0c3c8eb4d0dbbc785b6a3579b0ffedd9e42",
|
||||
]
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
resource "google_artifact_registry_repository" "my-repo" {
|
||||
provider = google-beta
|
||||
location = var.region
|
||||
repository_id = "${var.prefix}-repository"
|
||||
description = "repository to hold fleet container images for cloud run"
|
||||
format = "DOCKER"
|
||||
}
|
||||
|
|
@ -28,6 +28,10 @@ resource "random_pet" "suffix" {
|
|||
length = 1
|
||||
}
|
||||
|
||||
resource "random_password" "private_key" {
|
||||
length = 32
|
||||
}
|
||||
|
||||
resource "google_secret_manager_secret" "secret" {
|
||||
secret_id = "fleet-db-password-${random_pet.suffix.id}"
|
||||
replication {
|
||||
|
|
@ -35,6 +39,18 @@ resource "google_secret_manager_secret" "secret" {
|
|||
}
|
||||
}
|
||||
|
||||
resource "google_secret_manager_secret" "private_key" {
|
||||
secret_id = "fleet-private-key-${random_pet.suffix.id}"
|
||||
replication {
|
||||
automatic = true
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_secret_manager_secret_version" "private_key" {
|
||||
secret = google_secret_manager_secret.private_key.name
|
||||
secret_data = random_password.private_key.result
|
||||
}
|
||||
|
||||
resource "google_secret_manager_secret_version" "secret-version-data" {
|
||||
secret = google_secret_manager_secret.secret.name
|
||||
secret_data = module.fleet-mysql.generated_user_password
|
||||
|
|
@ -49,6 +65,13 @@ resource "google_secret_manager_secret_iam_member" "secret-access" {
|
|||
depends_on = [google_secret_manager_secret.secret]
|
||||
}
|
||||
|
||||
resource "google_secret_manager_secret_iam_member" "private-key-access" {
|
||||
secret_id = google_secret_manager_secret.private_key.id
|
||||
role = "roles/secretmanager.secretAccessor"
|
||||
member = "serviceAccount:${data.google_compute_default_service_account.default.email}"
|
||||
depends_on = [google_secret_manager_secret.private_key]
|
||||
}
|
||||
|
||||
resource "google_cloud_run_service" "default" {
|
||||
name = "${var.prefix}-backend"
|
||||
location = var.region
|
||||
|
|
@ -69,7 +92,7 @@ resource "google_cloud_run_service" "default" {
|
|||
memory = var.fleet_memory
|
||||
}
|
||||
}
|
||||
image = "${var.region}-docker.pkg.dev/${var.project_id}/${google_artifact_registry_repository.my-repo.name}/${var.image}"
|
||||
image = var.image
|
||||
ports {
|
||||
name = "http1"
|
||||
container_port = 8080
|
||||
|
|
@ -82,6 +105,43 @@ resource "google_cloud_run_service" "default" {
|
|||
name = "FLEET_MYSQL_DATABASE"
|
||||
value = var.db_name
|
||||
}
|
||||
env {
|
||||
name = "FLEET_S3_SOFTWARE_INSTALLERS_BUCKET"
|
||||
value = google_storage_bucket.software_installers.id
|
||||
}
|
||||
env {
|
||||
name = "FLEET_S3_SOFTWARE_INSTALLERS_ACCESS_KEY_ID"
|
||||
value = google_storage_hmac_key.key.access_id
|
||||
}
|
||||
env {
|
||||
name = "FLEET_S3_SOFTWARE_INSTALLERS_SECRET_ACCESS_KEY"
|
||||
value = google_storage_hmac_key.key.secret
|
||||
}
|
||||
env {
|
||||
name = "FLEET_S3_SOFTWARE_INSTALLERS_ENDPOINT_URL"
|
||||
value = "https://storage.googleapis.com"
|
||||
}
|
||||
env {
|
||||
// software_installers_force_s3_path_style
|
||||
name = "FLEET_S3_SOFTWARE_INSTALLERS_FORCE_S3_PATH_STYLE"
|
||||
value = "true"
|
||||
}
|
||||
env {
|
||||
name = "FLEET_S3_SOFTWARE_INSTALLERS_REGION"
|
||||
value = "auto"
|
||||
}
|
||||
env {
|
||||
name = "FLEET_LOGGING_JSON"
|
||||
value = "true"
|
||||
}
|
||||
env {
|
||||
name = "FLEET_LOGGING_DEBUG"
|
||||
value = var.debug_logging
|
||||
}
|
||||
env {
|
||||
name = "FLEET_LICENSE_KEY"
|
||||
value = var.license_key
|
||||
}
|
||||
env {
|
||||
name = "FLEET_SERVER_TLS"
|
||||
value = false
|
||||
|
|
@ -103,6 +163,15 @@ resource "google_cloud_run_service" "default" {
|
|||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "FLEET_SERVER_PRIVATE_KEY"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = google_secret_manager_secret.private_key.secret_id
|
||||
key = "latest"
|
||||
}
|
||||
}
|
||||
}
|
||||
command = ["/bin/sh"]
|
||||
args = [
|
||||
"-c",
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ terraform {
|
|||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = "4.9.0"
|
||||
version = "4.51.0"
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
|
|
|
|||
|
|
@ -21,31 +21,6 @@ using [Serverless VPC Access Connector](https://cloud.google.com/sql/docs/mysql/
|
|||
We are running Redis using [Google Cloud Memorystore (Redis engine)](https://cloud.google.com/memorystore). This can run in cluster mode, but by default we
|
||||
are running in standalone mode.
|
||||
|
||||
### Pushing the Fleet image into Google Artifact registry
|
||||
|
||||
More details can be found [here](https://cloud.google.com/artifact-registry/docs/docker/pushing-and-pulling).
|
||||
|
||||
Login with gcloud helper:
|
||||
|
||||
```shell
|
||||
gcloud auth configure-docker \
|
||||
us-central1-docker.pkg.dev
|
||||
```
|
||||
|
||||
Pull latest image:
|
||||
|
||||
`docker pull <latest fleet version>` for example `docker pull fleetdm/fleet:v4.10.0`
|
||||
|
||||
Tag it:
|
||||
|
||||
```
|
||||
docker tag fleetdm/fleet:v10.0.0 us-central1-docker.pkg.dev/<project_id>/fleet-repository/fleet:v10.0.0
|
||||
```
|
||||
|
||||
Push to Google Artifact registry:
|
||||
|
||||
`docker push us-central1-docker.pkg.dev/<project_id>/fleet-repository/fleet:v4.9.1`
|
||||
|
||||
### GCP Managed Certificates
|
||||
|
||||
In this example we are using [GCP Managed Certificates](https://cloud.google.com/load-balancing/docs/ssl-certificates/google-managed-certs) to handle TLS and TLS termination at the LoadBalancer.
|
||||
|
|
|
|||
23
infrastructure/dogfood/terraform/gcp/storage.tf
Normal file
23
infrastructure/dogfood/terraform/gcp/storage.tf
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
data "google_client_config" "current" {}
|
||||
|
||||
resource "google_service_account" "service_account" {
|
||||
account_id = "fleet-svc"
|
||||
}
|
||||
|
||||
resource "google_storage_hmac_key" "key" {
|
||||
service_account_email = google_service_account.service_account.email
|
||||
}
|
||||
|
||||
resource "google_storage_bucket" "software_installers" {
|
||||
name = var.software_installers_bucket_name
|
||||
location = data.google_client_config.current.region
|
||||
force_destroy = true
|
||||
|
||||
uniform_bucket_level_access = true
|
||||
}
|
||||
|
||||
resource "google_storage_bucket_iam_member" "hmac_sa_storage_admin" {
|
||||
bucket = google_storage_bucket.software_installers.name
|
||||
role = "roles/storage.objectAdmin"
|
||||
member = "serviceAccount:${google_service_account.service_account.email}"
|
||||
}
|
||||
|
|
@ -68,5 +68,18 @@ variable "redis_mem" {
|
|||
}
|
||||
|
||||
variable "image" {
|
||||
default = "fleet:v4.54.0"
|
||||
default = "fleetdm/fleet:v4.54.0"
|
||||
}
|
||||
|
||||
variable "software_installers_bucket_name" {
|
||||
default = "fleet-software-installers"
|
||||
}
|
||||
|
||||
variable "license_key" {
|
||||
default = ""
|
||||
description = "Fleet license key"
|
||||
}
|
||||
|
||||
variable "debug_logging" {
|
||||
default = "false"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,3 +43,16 @@ module "private-service-access" {
|
|||
vpc_network = module.vpc.network_name
|
||||
depends_on = [module.vpc]
|
||||
}
|
||||
|
||||
module "cloud_router" {
|
||||
source = "terraform-google-modules/cloud-router/google"
|
||||
version = "~> 6.0"
|
||||
name = "fleet-cloud-router"
|
||||
project = var.project_id
|
||||
network = module.vpc.network_name
|
||||
region = var.region
|
||||
|
||||
nats = [{
|
||||
name = "fleet-vpc-nat"
|
||||
}]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -343,7 +343,7 @@ func TestCalendarEventsMultipleHosts(t *testing.T) {
|
|||
email string,
|
||||
startTime, endTime time.Time,
|
||||
data []byte,
|
||||
timeZone string,
|
||||
timeZone *string,
|
||||
hostID uint,
|
||||
webhookStatus fleet.CalendarWebhookStatus,
|
||||
) (*fleet.CalendarEvent, error) {
|
||||
|
|
@ -633,7 +633,7 @@ func TestCalendarEvents1KHosts(t *testing.T) {
|
|||
email string,
|
||||
startTime, endTime time.Time,
|
||||
data []byte,
|
||||
timeZone string,
|
||||
timeZone *string,
|
||||
hostID uint,
|
||||
webhookStatus fleet.CalendarWebhookStatus,
|
||||
) (*fleet.CalendarEvent, error) {
|
||||
|
|
@ -923,7 +923,7 @@ func TestEventBody(t *testing.T) {
|
|||
email string,
|
||||
startTime, endTime time.Time,
|
||||
data []byte,
|
||||
timeZone string,
|
||||
timeZone *string,
|
||||
hostID uint,
|
||||
webhookStatus fleet.CalendarWebhookStatus,
|
||||
) (*fleet.CalendarEvent, error) {
|
||||
|
|
|
|||
|
|
@ -5,9 +5,10 @@ import (
|
|||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/google/uuid"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/fleetdm/fleet/v4/server/contexts/ctxerr"
|
||||
"github.com/fleetdm/fleet/v4/server/fleet"
|
||||
"github.com/jmoiron/sqlx"
|
||||
|
|
@ -22,7 +23,7 @@ func (ds *Datastore) CreateOrUpdateCalendarEvent(
|
|||
startTime time.Time,
|
||||
endTime time.Time,
|
||||
data []byte,
|
||||
timeZone string,
|
||||
timeZone *string,
|
||||
hostID uint,
|
||||
webhookStatus fleet.CalendarWebhookStatus,
|
||||
) (*fleet.CalendarEvent, error) {
|
||||
|
|
@ -153,7 +154,7 @@ func (ds *Datastore) GetCalendarEventDetailsByUUID(ctx context.Context, uuidStr
|
|||
}
|
||||
|
||||
func (ds *Datastore) UpdateCalendarEvent(ctx context.Context, calendarEventID uint, uuidStr string, startTime time.Time, endTime time.Time,
|
||||
data []byte, timeZone string) error {
|
||||
data []byte, timeZone *string) error {
|
||||
UUID, err := uuid.Parse(uuidStr)
|
||||
if err != nil {
|
||||
return ctxerr.Wrap(ctx, err, "invalid uuid")
|
||||
|
|
|
|||
|
|
@ -2,12 +2,13 @@ package mysql
|
|||
|
||||
import (
|
||||
"context"
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/fleetdm/fleet/v4/server/fleet"
|
||||
"github.com/fleetdm/fleet/v4/server/ptr"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
|
@ -60,14 +61,14 @@ func testUpdateCalendarEvent(t *testing.T, ds *Datastore) {
|
|||
endTime1 := startTime1.Add(30 * time.Minute)
|
||||
timeZone := "America/Argentina/Buenos_Aires"
|
||||
eventUUID := uuid.New().String()
|
||||
calendarEvent, err := ds.CreateOrUpdateCalendarEvent(ctx, eventUUID, "foo@example.com", startTime1, endTime1, []byte(`{}`), timeZone,
|
||||
calendarEvent, err := ds.CreateOrUpdateCalendarEvent(ctx, eventUUID, "foo@example.com", startTime1, endTime1, []byte(`{}`), &timeZone,
|
||||
host.ID, fleet.CalendarWebhookStatusNone)
|
||||
require.NoError(t, err)
|
||||
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
eventUUIDNew := uuid.New().String()
|
||||
err = ds.UpdateCalendarEvent(ctx, calendarEvent.ID, eventUUIDNew, startTime1, endTime1, []byte(`{}`), timeZone)
|
||||
err = ds.UpdateCalendarEvent(ctx, calendarEvent.ID, eventUUIDNew, startTime1, endTime1, []byte(`{}`), &timeZone)
|
||||
require.NoError(t, err)
|
||||
|
||||
calendarEvent2, err := ds.GetCalendarEvent(ctx, "foo@example.com")
|
||||
|
|
@ -117,15 +118,15 @@ func testCreateOrUpdateCalendarEvent(t *testing.T, ds *Datastore) {
|
|||
startTime1 := time.Now()
|
||||
endTime1 := startTime1.Add(30 * time.Minute)
|
||||
eventUUID := uuid.New().String()
|
||||
calendarEvent, err := ds.CreateOrUpdateCalendarEvent(ctx, eventUUID, "foo@example.com", startTime1, endTime1, []byte(`{}`), timeZone,
|
||||
calendarEvent, err := ds.CreateOrUpdateCalendarEvent(ctx, eventUUID, "foo@example.com", startTime1, endTime1, []byte(`{}`), &timeZone,
|
||||
host.ID, fleet.CalendarWebhookStatusNone)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, calendarEvent.TimeZone, timeZone)
|
||||
require.Equal(t, *calendarEvent.TimeZone, timeZone)
|
||||
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
eventUUID2 := uuid.New().String()
|
||||
calendarEvent2, err := ds.CreateOrUpdateCalendarEvent(ctx, eventUUID2, "foo@example.com", startTime1, endTime1, []byte(`{}`), timeZone,
|
||||
calendarEvent2, err := ds.CreateOrUpdateCalendarEvent(ctx, eventUUID2, "foo@example.com", startTime1, endTime1, []byte(`{}`), &timeZone,
|
||||
host.ID, fleet.CalendarWebhookStatusNone)
|
||||
require.NoError(t, err)
|
||||
require.Greater(t, calendarEvent2.UpdatedAt, calendarEvent.UpdatedAt)
|
||||
|
|
@ -139,7 +140,7 @@ func testCreateOrUpdateCalendarEvent(t *testing.T, ds *Datastore) {
|
|||
startTime2 := startTime1.Add(1 * time.Hour)
|
||||
endTime2 := startTime1.Add(30 * time.Minute)
|
||||
calendarEvent3, err := ds.CreateOrUpdateCalendarEvent(ctx, eventUUID2, "foo@example.com", startTime2, endTime2,
|
||||
[]byte(`{"foo": "bar"}`), timeZone, host.ID, fleet.CalendarWebhookStatusPending)
|
||||
[]byte(`{"foo": "bar"}`), &timeZone, host.ID, fleet.CalendarWebhookStatusPending)
|
||||
require.NoError(t, err)
|
||||
require.Greater(t, calendarEvent3.UpdatedAt, calendarEvent2.UpdatedAt)
|
||||
require.WithinDuration(t, startTime2, calendarEvent3.StartTime, 1*time.Second)
|
||||
|
|
|
|||
|
|
@ -1874,7 +1874,6 @@ func (ds *Datastore) EnrollOrbit(ctx context.Context, isMDMEnabled bool, hostInf
|
|||
uuid = COALESCE(NULLIF(uuid, ''), ?),
|
||||
osquery_host_id = COALESCE(NULLIF(osquery_host_id, ''), ?),
|
||||
hardware_serial = COALESCE(NULLIF(hardware_serial, ''), ?),
|
||||
last_enrolled_at = NOW(),
|
||||
team_id = ?
|
||||
WHERE id = ?`
|
||||
_, err := tx.ExecContext(ctx, sqlUpdate,
|
||||
|
|
|
|||
|
|
@ -8258,7 +8258,9 @@ func testHostsEnrollOrbit(t *testing.T, ds *Datastore) {
|
|||
require.NoError(t, err)
|
||||
h2OrbitFetched, err := ds.Host(ctx, h2Orbit.ID)
|
||||
require.NoError(t, err)
|
||||
require.NotEqual(t, h1OsqueryFetched.LastEnrolledAt, h2OrbitFetched.LastEnrolledAt)
|
||||
// orbit should not update last_enrolled_at if re-enrolling (because last_enrolled_at
|
||||
// is to be set by osquery only).
|
||||
require.Equal(t, h1OsqueryFetched.LastEnrolledAt, h2OrbitFetched.LastEnrolledAt)
|
||||
time.Sleep(1 * time.Second) // to test the update of last_enrolled_at
|
||||
h2Osquery, err := ds.EnrollHost(ctx, false, dupUUID, dupUUID, dupHWSerial, uuid.New().String(), nil, 0)
|
||||
require.NoError(t, err)
|
||||
|
|
@ -9617,9 +9619,9 @@ func testListUpcomingHostMaintenanceWindows(t *testing.T, ds *Datastore) {
|
|||
startTime := time.Now().UTC().Add(30 * time.Minute)
|
||||
endTime := startTime.Add(30 * time.Minute)
|
||||
calendarEvent, err := ds.CreateOrUpdateCalendarEvent(ctx, uuid.New().String(), "foo@example.com", startTime, endTime, []byte(`{}`),
|
||||
timeZone, host.ID, fleet.CalendarWebhookStatusNone)
|
||||
&timeZone, host.ID, fleet.CalendarWebhookStatusNone)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, calendarEvent.TimeZone, timeZone)
|
||||
require.Equal(t, *calendarEvent.TimeZone, timeZone)
|
||||
|
||||
mWs, err = ds.ListUpcomingHostMaintenanceWindows(ctx, host.ID)
|
||||
require.NoError(t, err)
|
||||
|
|
|
|||
|
|
@ -3651,11 +3651,11 @@ func testGetTeamHostsPolicyMemberships(t *testing.T, ds *Datastore) {
|
|||
tZ := "America/Argentina/Buenos_Aires"
|
||||
now := time.Now()
|
||||
eventUUID1 := uuid.New().String()
|
||||
_, err = ds.CreateOrUpdateCalendarEvent(ctx, eventUUID1, "foo@example.com", now, now.Add(30*time.Minute), []byte(`{"foo": "bar"}`), tZ,
|
||||
_, err = ds.CreateOrUpdateCalendarEvent(ctx, eventUUID1, "foo@example.com", now, now.Add(30*time.Minute), []byte(`{"foo": "bar"}`), &tZ,
|
||||
host1.ID, fleet.CalendarWebhookStatusPending)
|
||||
require.NoError(t, err)
|
||||
eventUUID2 := uuid.New().String()
|
||||
_, err = ds.CreateOrUpdateCalendarEvent(ctx, eventUUID2, "bar@example.com", now, now.Add(30*time.Minute), []byte(`{"foo": "bar"}`), tZ,
|
||||
_, err = ds.CreateOrUpdateCalendarEvent(ctx, eventUUID2, "bar@example.com", now, now.Add(30*time.Minute), []byte(`{"foo": "bar"}`), &tZ,
|
||||
host6.ID, fleet.CalendarWebhookStatusPending)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
|
@ -3737,12 +3737,12 @@ func testGetTeamHostsPolicyMemberships(t *testing.T, ds *Datastore) {
|
|||
// Create a calendar event on host2 and host3.
|
||||
//
|
||||
now = time.Now()
|
||||
_, err = ds.CreateOrUpdateCalendarEvent(ctx, eventUUID1, "foo@example.com", now, now.Add(30*time.Minute), []byte(`{"foo": "bar"}`), tZ,
|
||||
_, err = ds.CreateOrUpdateCalendarEvent(ctx, eventUUID1, "foo@example.com", now, now.Add(30*time.Minute), []byte(`{"foo": "bar"}`), &tZ,
|
||||
host2.ID, fleet.CalendarWebhookStatusPending)
|
||||
require.NoError(t, err)
|
||||
eventUUID3 := uuid.New().String()
|
||||
calendarEventHost3, err := ds.CreateOrUpdateCalendarEvent(ctx, eventUUID3, "zoo@example.com", now, now.Add(30*time.Minute),
|
||||
[]byte(`{"foo": "bar"}`), tZ, host3.ID, fleet.CalendarWebhookStatusPending)
|
||||
[]byte(`{"foo": "bar"}`), &tZ, host3.ID, fleet.CalendarWebhookStatusPending)
|
||||
require.NoError(t, err)
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ type CalendarEvent struct {
|
|||
StartTime time.Time `db:"start_time"`
|
||||
EndTime time.Time `db:"end_time"`
|
||||
Data []byte `db:"event"`
|
||||
TimeZone string `db:"timezone"`
|
||||
TimeZone *string `db:"timezone"` // Only nil when event existed before addition of timezone column
|
||||
|
||||
UpdateCreateTimestamps
|
||||
}
|
||||
|
|
|
|||
|
|
@ -696,12 +696,12 @@ type Datastore interface {
|
|||
// Calendar events
|
||||
|
||||
CreateOrUpdateCalendarEvent(ctx context.Context, uuid string, email string, startTime time.Time, endTime time.Time, data []byte,
|
||||
timeZone string, hostID uint, webhookStatus CalendarWebhookStatus) (*CalendarEvent, error)
|
||||
timeZone *string, hostID uint, webhookStatus CalendarWebhookStatus) (*CalendarEvent, error)
|
||||
GetCalendarEvent(ctx context.Context, email string) (*CalendarEvent, error)
|
||||
GetCalendarEventDetailsByUUID(ctx context.Context, uuid string) (*CalendarEventDetails, error)
|
||||
DeleteCalendarEvent(ctx context.Context, calendarEventID uint) error
|
||||
UpdateCalendarEvent(ctx context.Context, calendarEventID uint, uuid string, startTime time.Time, endTime time.Time, data []byte,
|
||||
timeZone string) error
|
||||
timeZone *string) error
|
||||
GetHostCalendarEvent(ctx context.Context, hostID uint) (*HostCalendarEvent, *CalendarEvent, error)
|
||||
GetHostCalendarEventByEmail(ctx context.Context, email string) (*HostCalendarEvent, *CalendarEvent, error)
|
||||
UpdateHostCalendarWebhookStatus(ctx context.Context, hostID uint, status CalendarWebhookStatus) error
|
||||
|
|
|
|||
|
|
@ -506,7 +506,7 @@ type DeleteSoftwareVulnerabilitiesFunc func(ctx context.Context, vulnerabilities
|
|||
|
||||
type DeleteOutOfDateVulnerabilitiesFunc func(ctx context.Context, source fleet.VulnerabilitySource, duration time.Duration) error
|
||||
|
||||
type CreateOrUpdateCalendarEventFunc func(ctx context.Context, uuid string, email string, startTime time.Time, endTime time.Time, data []byte, timeZone string, hostID uint, webhookStatus fleet.CalendarWebhookStatus) (*fleet.CalendarEvent, error)
|
||||
type CreateOrUpdateCalendarEventFunc func(ctx context.Context, uuid string, email string, startTime time.Time, endTime time.Time, data []byte, timeZone *string, hostID uint, webhookStatus fleet.CalendarWebhookStatus) (*fleet.CalendarEvent, error)
|
||||
|
||||
type GetCalendarEventFunc func(ctx context.Context, email string) (*fleet.CalendarEvent, error)
|
||||
|
||||
|
|
@ -514,7 +514,7 @@ type GetCalendarEventDetailsByUUIDFunc func(ctx context.Context, uuid string) (*
|
|||
|
||||
type DeleteCalendarEventFunc func(ctx context.Context, calendarEventID uint) error
|
||||
|
||||
type UpdateCalendarEventFunc func(ctx context.Context, calendarEventID uint, uuid string, startTime time.Time, endTime time.Time, data []byte, timeZone string) error
|
||||
type UpdateCalendarEventFunc func(ctx context.Context, calendarEventID uint, uuid string, startTime time.Time, endTime time.Time, data []byte, timeZone *string) error
|
||||
|
||||
type GetHostCalendarEventFunc func(ctx context.Context, hostID uint) (*fleet.HostCalendarEvent, *fleet.CalendarEvent, error)
|
||||
|
||||
|
|
@ -4205,7 +4205,7 @@ func (s *DataStore) DeleteOutOfDateVulnerabilities(ctx context.Context, source f
|
|||
return s.DeleteOutOfDateVulnerabilitiesFunc(ctx, source, duration)
|
||||
}
|
||||
|
||||
func (s *DataStore) CreateOrUpdateCalendarEvent(ctx context.Context, uuid string, email string, startTime time.Time, endTime time.Time, data []byte, timeZone string, hostID uint, webhookStatus fleet.CalendarWebhookStatus) (*fleet.CalendarEvent, error) {
|
||||
func (s *DataStore) CreateOrUpdateCalendarEvent(ctx context.Context, uuid string, email string, startTime time.Time, endTime time.Time, data []byte, timeZone *string, hostID uint, webhookStatus fleet.CalendarWebhookStatus) (*fleet.CalendarEvent, error) {
|
||||
s.mu.Lock()
|
||||
s.CreateOrUpdateCalendarEventFuncInvoked = true
|
||||
s.mu.Unlock()
|
||||
|
|
@ -4233,7 +4233,7 @@ func (s *DataStore) DeleteCalendarEvent(ctx context.Context, calendarEventID uin
|
|||
return s.DeleteCalendarEventFunc(ctx, calendarEventID)
|
||||
}
|
||||
|
||||
func (s *DataStore) UpdateCalendarEvent(ctx context.Context, calendarEventID uint, uuid string, startTime time.Time, endTime time.Time, data []byte, timeZone string) error {
|
||||
func (s *DataStore) UpdateCalendarEvent(ctx context.Context, calendarEventID uint, uuid string, startTime time.Time, endTime time.Time, data []byte, timeZone *string) error {
|
||||
s.mu.Lock()
|
||||
s.UpdateCalendarEventFuncInvoked = true
|
||||
s.mu.Unlock()
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ func TestAPIRoutesConflicts(t *testing.T) {
|
|||
}
|
||||
var cases []testCase
|
||||
|
||||
// build the test cases: for each route, generate a request designed to match
|
||||
// Build the test cases: for each route, generate a request designed to match
|
||||
// it, and override its handler to return a unique status code. If the
|
||||
// request doesn't result in that status code, then some other route
|
||||
// conflicts with it and took precedence - a route conflict. The route's name
|
||||
|
|
|
|||
|
|
@ -994,7 +994,9 @@ type refetchHostResponse struct {
|
|||
Err error `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
func (r refetchHostResponse) error() error { return r.Err }
|
||||
func (r refetchHostResponse) error() error {
|
||||
return r.Err
|
||||
}
|
||||
|
||||
func refetchHostEndpoint(ctx context.Context, request interface{}, svc fleet.Service) (errorer, error) {
|
||||
req := request.(*refetchHostRequest)
|
||||
|
|
|
|||
|
|
@ -8334,9 +8334,8 @@ func (s *integrationTestSuite) TestGetHostMaintenanceWindow() {
|
|||
StartTime: startTime,
|
||||
EndTime: endTime,
|
||||
Data: []byte(`{}`),
|
||||
// will replace with NULL - db method doesn't allow nil
|
||||
TimeZone: "",
|
||||
UUID: uuid.New().String(),
|
||||
TimeZone: nil,
|
||||
UUID: uuid.New().String(),
|
||||
}
|
||||
|
||||
dsEvent, err := s.ds.CreateOrUpdateCalendarEvent(ctx, testEvent.UUID, testEvent.Email, testEvent.StartTime, testEvent.EndTime,
|
||||
|
|
@ -8371,7 +8370,7 @@ func (s *integrationTestSuite) TestGetHostMaintenanceWindow() {
|
|||
|
||||
// update the timezone
|
||||
_, err = s.ds.CreateOrUpdateCalendarEvent(ctx, testEvent.UUID, testEvent.Email, testEvent.StartTime, testEvent.EndTime, testEvent.Data,
|
||||
timeZone, host.ID, fleet.CalendarWebhookStatusNone)
|
||||
&timeZone, host.ID, fleet.CalendarWebhookStatusNone)
|
||||
require.NoError(t, err)
|
||||
|
||||
time.Sleep(1 * time.Second)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
services:
|
||||
mysql:
|
||||
platform: ${FLEET_MYSQL_PLATFORM:-linux/x86_64}
|
||||
image: mysql:5.7
|
||||
image: mysql:8.0.36
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: toor
|
||||
MYSQL_DATABASE: fleet
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
docker run --rm --network fleet_default ${FLEET_MYSQL_IMAGE:-mysql:5.7} bash -c 'mysqldump -hmysql -uroot -ptoor --default-character-set=utf8mb4 fleet | gzip -' > backup.sql.gz
|
||||
docker run --rm --network fleet_default ${FLEET_MYSQL_IMAGE:-mysql:8.0.36} bash -c 'mysqldump -hmysql -uroot -ptoor --default-character-set=utf8mb4 fleet | gzip -' > backup.sql.gz
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
docker run --rm -i --network fleet_default ${FLEET_MYSQL_IMAGE:-mysql:5.7} bash -c 'gzip -dc - | mysql -hmysql -uroot -ptoor fleet' < backup.sql.gz
|
||||
docker run --rm -i --network fleet_default ${FLEET_MYSQL_IMAGE:-mysql:8.0.36} bash -c 'gzip -dc - | mysql -hmysql -uroot -ptoor fleet' < backup.sql.gz
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
docker run --rm -i --network fleet_default mysql:5.7 bash -c 'gzip -kdc - | mysql -hmysql_test -uroot -ptoor e2e' < tools/testdata/e2e_software_test.sql.gz
|
||||
|
||||
docker run --rm -i --network fleet_default mysql:8.0.36 bash -c 'gzip -kdc - | mysql -hmysql_test -uroot -ptoor e2e' < tools/testdata/e2e_software_test.sql.gz
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
version: "2"
|
||||
services:
|
||||
mysql_main:
|
||||
image: ${FLEET_MYSQL_IMAGE:-mysql:5.7}
|
||||
image: ${FLEET_MYSQL_IMAGE:-mysql:8.0.36}
|
||||
platform: ${FLEET_MYSQL_PLATFORM:-linux/x86_64}
|
||||
volumes:
|
||||
- mysql-persistent-volume-replica-main:/tmp
|
||||
|
|
@ -27,7 +27,7 @@ services:
|
|||
- "3308:3306"
|
||||
|
||||
mysql_read_replica:
|
||||
image: ${FLEET_MYSQL_IMAGE:-mysql:5.7}
|
||||
image: ${FLEET_MYSQL_IMAGE:-mysql:8.0.36}
|
||||
platform: ${FLEET_MYSQL_PLATFORM:-linux/x86_64}
|
||||
volumes:
|
||||
- mysql-persistent-volume-replica-read:/tmp
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ networks:
|
|||
|
||||
services:
|
||||
mysql01:
|
||||
image: mysql:5.7
|
||||
image: mysql:8.0.36
|
||||
platform: linux/x86_64
|
||||
volumes:
|
||||
- .:/data
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ docker volume rm fleet_mysql-persistent-volume
|
|||
|
||||
# Start dependencies using Percona XtraDB as MySQL server.
|
||||
# NOTE: To troubleshoot, remove `>/dev/null`.
|
||||
FLEET_MYSQL_IMAGE=percona/percona-xtradb-cluster:5.7.25 docker compose up >/dev/null 2>&1 &
|
||||
FLEET_MYSQL_IMAGE=percona/percona-xtradb-cluster:8.0.36 docker compose up >/dev/null 2>&1 &
|
||||
|
||||
export MYSQL_PWD=toor
|
||||
|
||||
|
|
@ -39,4 +39,4 @@ mysql --host 127.0.0.1 --port 3306 -uroot -e 'SET GLOBAL pxc_strict_mode=ENFORCI
|
|||
# Run migrations from fleet-v4.42.0 up to latest to catch any future bugs when running with `pxc_strict_mode=ENFORCING`.
|
||||
git checkout main
|
||||
make generate && make fleet
|
||||
./build/fleet prepare db --dev --logging_debug
|
||||
./build/fleet prepare db --dev --logging_debug
|
||||
|
|
|
|||
|
|
@ -78,7 +78,6 @@ module.exports = {
|
|||
'sampfluger88',
|
||||
'ireedy',
|
||||
'mostlikelee',
|
||||
'willmayhone88',
|
||||
'pacamaster',
|
||||
'AnthonySnyder8',
|
||||
'jahzielv',
|
||||
|
|
|
|||
Loading…
Reference in a new issue