diff --git a/.github/workflows/secure.yml b/.github/workflows/secure.yml index e49e66f3..1ec00902 100644 --- a/.github/workflows/secure.yml +++ b/.github/workflows/secure.yml @@ -21,14 +21,13 @@ jobs: security-events: write steps: - uses: actions/checkout@v4 - - run: semgrep scan --sarif --output=semgrep.sarif --error --severity=WARNING + - run: semgrep scan --sarif --output=semgrep.sarif --error --severity=WARNING --severity=ERROR env: SEMGREP_RULES: >- p/command-injection p/comment p/cwe-top-25 p/default - p/gitlab p/gitleaks p/golang p/gosec @@ -65,6 +64,7 @@ jobs: TRIVY_severity: MEDIUM,HIGH TRIVY_EXIT_CODE: 1 TRIVY_IGNOREFILE: .trivyignore.yml + TRIVY_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-db - uses: github/codeql-action/upload-sarif@v3 with: sarif_file: trivy.sarif diff --git a/.semgrepignore b/.semgrepignore index 0fbb4489..01548a20 100644 --- a/.semgrepignore +++ b/.semgrepignore @@ -1 +1,2 @@ website/ +*_test.go diff --git a/GNUmakefile b/GNUmakefile index e55ef800..2c5de116 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -45,4 +45,27 @@ ifeq (,$(wildcard $(GOPATH)/src/$(WEBSITE_REPO))) endif @$(MAKE) -C $(GOPATH)/src/$(WEBSITE_REPO) website-provider-test PROVIDER_PATH=$(shell pwd) PROVIDER_NAME=$(PKG_NAME) -.PHONY: golangci-lint build test testacc fmt test-compile website website-test + +# CLI reference: +# https://semgrep.dev/docs/cli-reference +semgrep: + docker run --rm -v ${PWD}:/app:ro -w /app semgrep/semgrep semgrep scan --error --metrics=off \ + --config=p/command-injection \ + --config=p/comment \ + --config=p/cwe-top-25 \ + --config=p/default \ + --config=p/gitleaks \ + --config=p/golang \ + --config=p/gosec \ + --config=p/insecure-transport \ + --config=p/owasp-top-ten \ + --config=p/r2c-best-practices \ + --config=p/r2c-bug-scan \ + --config=p/r2c-security-audit \ + --config=p/secrets \ + --config=p/security-audit \ + --config=p/sql-injection \ + --config=p/xss \ + . + +.PHONY: golangci-lint build test testacc fmt test-compile semgrep website website-test diff --git a/go.mod b/go.mod index 39074835..6b3a0bdf 100644 --- a/go.mod +++ b/go.mod @@ -9,9 +9,9 @@ require ( github.com/selectel/craas-go v0.3.0 github.com/selectel/dbaas-go v0.12.1 github.com/selectel/domains-go v1.0.2 - github.com/selectel/go-selvpcclient/v3 v3.1.1 + github.com/selectel/go-selvpcclient/v3 v3.2.1 github.com/selectel/iam-go v0.4.1 - github.com/selectel/mks-go v0.15.0 + github.com/selectel/mks-go v0.16.0 github.com/selectel/secretsmanager-go v0.2.1 github.com/stretchr/testify v1.8.4 ) diff --git a/go.sum b/go.sum index 0eec4931..cee05dd0 100644 --- a/go.sum +++ b/go.sum @@ -168,12 +168,12 @@ github.com/selectel/dbaas-go v0.12.1 h1:u3mBMoHP/FnHucLqd1QBeBHjQ2WV4S88ewP97gCE github.com/selectel/dbaas-go v0.12.1/go.mod h1:Ffq6RQ4PmgZX8eL9oXsaKDc0lzbCK9wadyDV6AHaz/k= github.com/selectel/domains-go v1.0.2 h1:Si6iGaMnTFJxwiJVI50DOdZnwcxc87kqaWrVQYW0a4U= github.com/selectel/domains-go v1.0.2/go.mod h1:SugRKfq4sTpnOHquslCpzda72wV8u0cMBHx0C0l+bzA= -github.com/selectel/go-selvpcclient/v3 v3.1.1 h1:C1q2LqqosiapoLpnGITGmysg0YCSQYDo2Gh69CioevM= -github.com/selectel/go-selvpcclient/v3 v3.1.1/go.mod h1:NM7IXhh1IzqZ88DOw1Qc5Ez3tULLViXo95l5+rKPuyQ= +github.com/selectel/go-selvpcclient/v3 v3.2.1 h1:ny6WIAMiHzKxOgOEnwcWE79wIQij1AHHylzPA41MXCw= +github.com/selectel/go-selvpcclient/v3 v3.2.1/go.mod h1:3EfSf8aEWyhspOGbvZ6mvnFg7JN5uckxNyBFPGWsXNQ= github.com/selectel/iam-go v0.4.1 h1:grncCGkPVCM6nwqSTk+q15M5ZO6S/Pe0AIbbmKtm6gU= github.com/selectel/iam-go v0.4.1/go.mod h1:OIAkW7MZK97YUm+uvUgYbgDhkI9SdzTCxwd4yZoOR1o= -github.com/selectel/mks-go v0.15.0 h1:0ytV5DiQAgbojKA0ukBjtwfWBSQh658nF3mhjZTrWj8= -github.com/selectel/mks-go v0.15.0/go.mod h1:VxtV3dzwgOEzZc+9VMQb9DvxfSlej2ZQ8jnT8kqIGgU= +github.com/selectel/mks-go v0.16.0 h1:qE4kMKQQV6iluu1W0WTzu3NJhXghS8GF20fIzV+3FOU= +github.com/selectel/mks-go v0.16.0/go.mod h1:VxtV3dzwgOEzZc+9VMQb9DvxfSlej2ZQ8jnT8kqIGgU= github.com/selectel/secretsmanager-go v0.2.1 h1:OSBrA/07lm/Ecpwg59IJHFAoUHZR29oyfwUgTpr/dos= github.com/selectel/secretsmanager-go v0.2.1/go.mod h1:DUPexhiJWLTyZEvse7grJWdcA8p8TEI93gNu1dDu7Yg= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= diff --git a/selectel/resource_selectel_mks_cluster_v1.go b/selectel/resource_selectel_mks_cluster_v1.go index 37ba43ea..73997a40 100644 --- a/selectel/resource_selectel_mks_cluster_v1.go +++ b/selectel/resource_selectel_mks_cluster_v1.go @@ -146,6 +146,12 @@ func resourceMKSClusterV1() *schema.Resource { Default: false, ForceNew: true, }, + "enable_audit_logs": { + Type: schema.TypeBool, + Optional: true, + Default: false, + ForceNew: false, + }, }, } } @@ -175,6 +181,7 @@ func resourceMKSClusterV1Create(ctx context.Context, d *schema.ResourceData, met enablePodSecurityPolicy := d.Get("enable_pod_security_policy").(bool) zonal := d.Get("zonal").(bool) privateKubeAPI := d.Get("private_kube_api").(bool) + enableAuditLogs := d.Get("enable_audit_logs").(bool) // Check if "enable_patch_version_auto_upgrade" and "zonal" arguments are both not set to true. if enablePatchVersionAutoUpgrade && zonal { @@ -205,6 +212,9 @@ func resourceMKSClusterV1Create(ctx context.Context, d *schema.ResourceData, met EnablePodSecurityPolicy: enablePodSecurityPolicy, FeatureGates: featureGates, AdmissionControllers: admissionControllers, + AuditLogs: cluster.AuditLogs{ + Enabled: enableAuditLogs, + }, }, Zonal: &zonal, PrivateKubeAPI: &privateKubeAPI, @@ -271,6 +281,7 @@ func resourceMKSClusterV1Read(ctx context.Context, d *schema.ResourceData, meta d.Set("enable_pod_security_policy", mksCluster.KubernetesOptions.EnablePodSecurityPolicy) d.Set("zonal", mksCluster.Zonal) d.Set("private_kube_api", mksCluster.PrivateKubeAPI) + d.Set("enable_audit_logs", mksCluster.KubernetesOptions.AuditLogs.Enabled) return nil } @@ -319,6 +330,11 @@ func resourceMKSClusterV1Update(ctx context.Context, d *schema.ResourceData, met } kubeOptions.AdmissionControllers = v } + if d.HasChange("enable_audit_logs") { + v := d.Get("enable_audit_logs").(bool) + kubeOptions.AuditLogs.Enabled = v + } + updateOpts.KubernetesOptions = kubeOptions if updateOpts != (cluster.UpdateOpts{}) { diff --git a/selectel/resource_selectel_mks_cluster_v1_test.go b/selectel/resource_selectel_mks_cluster_v1_test.go index 94dcd2aa..c2f2cd1c 100644 --- a/selectel/resource_selectel_mks_cluster_v1_test.go +++ b/selectel/resource_selectel_mks_cluster_v1_test.go @@ -56,6 +56,7 @@ func TestAccMKSClusterV1Basic(t *testing.T) { resource.TestCheckResourceAttr("selectel_mks_cluster_v1.cluster_tf_acc_test_1", "status", "ACTIVE"), resource.TestCheckResourceAttr("selectel_mks_cluster_v1.cluster_tf_acc_test_1", "feature_gates.0", defaultFeatureGates[0]), resource.TestCheckResourceAttr("selectel_mks_cluster_v1.cluster_tf_acc_test_1", "admission_controllers.0", defaultAdmissionControllers[0]), + resource.TestCheckResourceAttr("selectel_mks_cluster_v1.cluster_tf_acc_test_1", "enable_audit_logs", "false"), ), }, { @@ -71,6 +72,7 @@ func TestAccMKSClusterV1Basic(t *testing.T) { resource.TestCheckResourceAttr("selectel_mks_cluster_v1.cluster_tf_acc_test_1", "status", "ACTIVE"), resource.TestCheckResourceAttr("selectel_mks_cluster_v1.cluster_tf_acc_test_1", "feature_gates.0", defaultFeatureGates[1]), resource.TestCheckResourceAttr("selectel_mks_cluster_v1.cluster_tf_acc_test_1", "admission_controllers.0", defaultAdmissionControllers[1]), + resource.TestCheckResourceAttr("selectel_mks_cluster_v1.cluster_tf_acc_test_1", "enable_audit_logs", "true"), ), }, }, @@ -107,6 +109,7 @@ func TestAccMKSClusterV1Zonal(t *testing.T) { resource.TestCheckResourceAttr("selectel_mks_cluster_v1.cluster_tf_acc_test_1", "private_kube_api", "false"), resource.TestCheckResourceAttr("selectel_mks_cluster_v1.cluster_tf_acc_test_1", "maintenance_window_start", maintenanceWindowStart), resource.TestCheckResourceAttr("selectel_mks_cluster_v1.cluster_tf_acc_test_1", "status", "ACTIVE"), + resource.TestCheckResourceAttr("selectel_mks_cluster_v1.cluster_tf_acc_test_1", "enable_audit_logs", "true"), ), }, }, @@ -143,6 +146,7 @@ func TestAccMKSClusterV1PrivateKubeAPI(t *testing.T) { resource.TestCheckResourceAttr("selectel_mks_cluster_v1.cluster_tf_acc_test_1", "private_kube_api", "true"), resource.TestCheckResourceAttr("selectel_mks_cluster_v1.cluster_tf_acc_test_1", "maintenance_window_start", maintenanceWindowStart), resource.TestCheckResourceAttr("selectel_mks_cluster_v1.cluster_tf_acc_test_1", "status", "ACTIVE"), + resource.TestCheckResourceAttr("selectel_mks_cluster_v1.cluster_tf_acc_test_1", "enable_audit_logs", "false"), ), }, }, @@ -290,6 +294,7 @@ resource "selectel_mks_cluster_v1" "cluster_tf_acc_test_1" { enable_pod_security_policy = false feature_gates = [%s] admission_controllers = [%s] + enable_audit_logs = true }`, projectName, clusterName, kubeVersion, maintenanceWindowStart, flatFeatureGates, flatAdmissionControllers) } @@ -306,6 +311,7 @@ func testAccMKSClusterV1Zonal(projectName, clusterName, kubeVersion, maintenance maintenance_window_start = "%s" enable_patch_version_auto_upgrade = false zonal = true + enable_audit_logs = true }`, projectName, clusterName, kubeVersion, maintenanceWindowStart) } @@ -323,6 +329,7 @@ func testAccMKSClusterV1PrivateKubeAPI(projectName, clusterName, kubeVersion, ma enable_patch_version_auto_upgrade = false zonal = false private_kube_api = true + enable_audit_logs = false }`, projectName, clusterName, kubeVersion, maintenanceWindowStart) } diff --git a/selectel/resource_selectel_vpc_keypair_v2.go b/selectel/resource_selectel_vpc_keypair_v2.go index b4547af9..7069960f 100644 --- a/selectel/resource_selectel_vpc_keypair_v2.go +++ b/selectel/resource_selectel_vpc_keypair_v2.go @@ -92,7 +92,7 @@ func resourceVPCKeypairV2Read(_ context.Context, d *schema.ResourceData, meta in if err != nil { return diag.FromErr(errParseID(objectKeypair, d.Id())) } - existingKeypairs, _, err := keypairs.List(selvpcClient) + existingKeypairs, _, err := keypairs.ListWithOpts(selvpcClient, keypairs.ListOpts{UserID: userID}) if err != nil { return diag.FromErr(errSearchingKeypair(keypairName, err)) } diff --git a/website/docs/d/mks_kubeconfig_v1.html.markdown b/website/docs/d/mks_kubeconfig_v1.html.markdown index 6ddb2799..41ddbf4d 100644 --- a/website/docs/d/mks_kubeconfig_v1.html.markdown +++ b/website/docs/d/mks_kubeconfig_v1.html.markdown @@ -37,9 +37,9 @@ data "selectel_mks_kubeconfig_v1" "kubeconfig" { provider "kubernetes" { host = data.selectel_mks_kubeconfig_v1.kubeconfig.server - client_certificate = data.selectel_mks_kubeconfig_v1.kubeconfig.cluster_ca_cert - client_key = data.selectel_mks_kubeconfig_v1.kubeconfig.client_key - cluster_ca_certificate = data.selectel_mks_kubeconfig_v1.kubeconfig.client_cert + client_certificate = base64decode(data.selectel_mks_kubeconfig_v1.kubeconfig.client_cert) + client_key = base64decode(data.selectel_mks_kubeconfig_v1.kubeconfig.client_key) + cluster_ca_certificate = base64decode(data.selectel_mks_kubeconfig_v1.kubeconfig.cluster_ca_cert) } output "kubeconfig" { @@ -65,4 +65,4 @@ output "kubeconfig" { * `client_key` - Client key for authorization. -* `client_cert` - Client certificate for authorization. \ No newline at end of file +* `client_cert` - Client certificate for authorization. diff --git a/website/docs/r/mks_cluster_v1.html.markdown b/website/docs/r/mks_cluster_v1.html.markdown index 0f144c79..df0b4ab9 100644 --- a/website/docs/r/mks_cluster_v1.html.markdown +++ b/website/docs/r/mks_cluster_v1.html.markdown @@ -72,7 +72,7 @@ resource "selectel_mks_cluster_v1" "basic_cluster" { * `feature_gates` - (Optional) Enables or disables feature gates for the cluster. You can retrieve the list of available feature gates with the [selectel_mks_feature_gates_v1](https://registry.terraform.io/providers/selectel/selectel/latest/docs/data-sources/mks_feature_gates_v1) data source. Learn more about [Feature gates](https://docs.selectel.ru/en/cloud/managed-kubernetes/clusters/feature-gates/). -* `admission_controllers` - (Optional) Enables or disables admission controllers for the cluster. You can retrieve the list of available admission controllers with the [selectel_mks_admission_controllers_v1](https://registry.terraform.io/providers/selectel/selectel/latest/docs/data-sources/mks_admission_controllers_v1) data source. Learn more about [Admission controllers](https://docs.selectel.ru/en/cloud/managed-kubernetes/clusters/admission-controllers/). +* `admission_controllers` - (Optional) Enables or disables admission controllers for the cluster. You can retrieve the list of available admission controllers with the [selectel_mks_admission_controllers_v1](https://registry.terraform.io/providers/selectel/selectel/latest/docs/data-sources/mks_admission_controllers_v1) data source. Learn more about [Admission controllers](https://docs.selectel.ru/en/cloud/managed-kubernetes/clusters/admission-controllers/). * `private_kube_api` - (Optional) Specifies if Kube API is available from the Internet. Changing this creates a new cluster. @@ -82,6 +82,14 @@ resource "selectel_mks_cluster_v1" "basic_cluster" { * `true` - Kube API is available only from the cluster network. +* `enable_audit_logs` - (Optional) Enables or disables collection of audit logs. Learn how to [configure export of audit logs to a logging system](https://docs.selectel.ru/en/cloud/managed-kubernetes/clusters/logs/#configure-export-of-audit-logs). + + Boolean flag: + + * `false` (default) - Audit logs are not collected and are not available for export; + + * `true` - Audit logs are collected and available for export. + ## Attributes Reference * `maintenance_window_end` - Time in UTC when maintenance in the cluster ends. The format is `hh:mm:ss`. Learn more about the [Maintenance window](https://docs.selectel.ru/en/cloud/managed-kubernetes/clusters/set-up-maintenance-window/).