From 6d50bf58c3603cf56b27ec7eebaafd172ad91023 Mon Sep 17 00:00:00 2001 From: Hugo Bollon Date: Tue, 26 Oct 2021 12:45:49 +0200 Subject: [PATCH] fix(swagger): move swagger redirection on / instead on /swagger/ (#221) * fix(swagger): move swagger redirection on / instead on /swagger/ docs(swagger): add exit_code field to submit plan request * feat(swagger): allow swagger port configuration --- api/api.go | 1 + api/api_test.go | 2 +- config/config.go | 7 ++++--- config/config_test.go | 14 ++++++++------ config/config_test.yml | 1 + docs/docs.go | 3 +++ docs/swagger.json | 3 +++ docs/swagger.yaml | 2 ++ main.go | 6 +++--- 9 files changed, 26 insertions(+), 13 deletions(-) diff --git a/api/api.go b/api/api.go index af84bce3..c975e176 100644 --- a/api/api.go +++ b/api/api.go @@ -24,6 +24,7 @@ type planPayload struct { GitCommit string `json:"git_commit"` CiURL string `json:"ci_url"` Source string `json:"source"` + ExitCode int `json:"exit_code"` PlanJSON datatypes.JSON `json:"plan_json" swaggertype:"object"` } diff --git a/api/api_test.go b/api/api_test.go index 501011ba..a1c283ad 100644 --- a/api/api_test.go +++ b/api/api_test.go @@ -540,7 +540,7 @@ func TestSubmitPlan(t *testing.T) { } buf := httptest.NewRecorder() - req := httptest.NewRequest(http.MethodPost, `/plans`, bytes.NewReader([]byte(`{"lineage":"lineage_value","terraform_version":"1.0.0","git_remote":"foo.com","git_commit":"#12345","ci_url":"","source":"","plan_json":{"format_version":"0.1","terraform_version":"0.12.6","planned_values":{"root_module":{"resources":[{"address":"aws_autoscaling_group.my_asg","mode":"managed","type":"aws_autoscaling_group","name":"my_asg","provider_name":"aws","schema_version":0,"values":{"availability_zones":["us-west-1a"],"desired_capacity":4,"enabled_metrics":null,"force_delete":true,"health_check_grace_period":300,"health_check_type":"ELB","initial_lifecycle_hook":[],"launch_configuration":"my_web_config","launch_template":[],"max_size":5,"metrics_granularity":"1Minute","min_elb_capacity":null,"min_size":1,"mixed_instances_policy":[],"name":"my_asg","name_prefix":null,"placement_group":null,"protect_from_scale_in":false,"suspended_processes":null,"tag":[],"tags":null,"termination_policies":null,"timeouts":null,"wait_for_capacity_timeout":"10m","wait_for_elb_capacity":null}},{"address":"aws_instance.web","mode":"managed","type":"aws_instance","name":"web","provider_name":"aws","schema_version":1,"values":{"ami":"ami-09b4b74c","credit_specification":[],"disable_api_termination":null,"ebs_optimized":null,"get_password_data":false,"iam_instance_profile":null,"instance_initiated_shutdown_behavior":null,"instance_type":"t2.micro","monitoring":null,"source_dest_check":true,"tags":null,"timeouts":null,"user_data":null,"user_data_base64":null}},{"address":"aws_launch_configuration.my_web_config","mode":"managed","type":"aws_launch_configuration","name":"my_web_config","provider_name":"aws","schema_version":0,"values":{"associate_public_ip_address":false,"enable_monitoring":true,"ephemeral_block_device":[],"iam_instance_profile":null,"image_id":"ami-09b4b74c","instance_type":"t2.micro","name":"my_web_config","name_prefix":null,"placement_tenancy":null,"security_groups":null,"spot_price":null,"user_data":null,"user_data_base64":null,"vpc_classic_link_id":null,"vpc_classic_link_security_groups":null}}]}},"resource_changes":[{"address":"aws_autoscaling_group.my_asg","mode":"managed","type":"aws_autoscaling_group","name":"my_asg","provider_name":"aws","change":{"actions":["create"],"before":null,"after":{"availability_zones":["us-west-1a"],"desired_capacity":4,"enabled_metrics":null,"force_delete":true,"health_check_grace_period":300,"health_check_type":"ELB","initial_lifecycle_hook":[],"launch_configuration":"my_web_config","launch_template":[],"max_size":5,"metrics_granularity":"1Minute","min_elb_capacity":null,"min_size":1,"mixed_instances_policy":[],"name":"my_asg","name_prefix":null,"placement_group":null,"protect_from_scale_in":false,"suspended_processes":null,"tag":[],"tags":null,"termination_policies":null,"timeouts":null,"wait_for_capacity_timeout":"10m","wait_for_elb_capacity":null},"after_unknown":{"arn":true,"availability_zones":[false],"default_cooldown":true,"id":true,"initial_lifecycle_hook":[],"launch_template":[],"load_balancers":true,"mixed_instances_policy":[],"service_linked_role_arn":true,"tag":[],"target_group_arns":true,"vpc_zone_identifier":true}}},{"address":"aws_instance.web","mode":"managed","type":"aws_instance","name":"web","provider_name":"aws","change":{"actions":["create"],"before":null,"after":{"ami":"ami-09b4b74c","credit_specification":[],"disable_api_termination":null,"ebs_optimized":null,"get_password_data":false,"iam_instance_profile":null,"instance_initiated_shutdown_behavior":null,"instance_type":"t2.micro","monitoring":null,"source_dest_check":true,"tags":null,"timeouts":null,"user_data":null,"user_data_base64":null},"after_unknown":{"arn":true,"associate_public_ip_address":true,"availability_zone":true,"cpu_core_count":true,"cpu_threads_per_core":true,"credit_specification":[],"ebs_block_device":true,"ephemeral_block_device":true,"host_id":true,"id":true,"instance_state":true,"ipv6_address_count":true,"ipv6_addresses":true,"key_name":true,"network_interface":true,"network_interface_id":true,"password_data":true,"placement_group":true,"primary_network_interface_id":true,"private_dns":true,"private_ip":true,"public_dns":true,"public_ip":true,"root_block_device":true,"security_groups":true,"subnet_id":true,"tenancy":true,"volume_tags":true,"vpc_security_group_ids":true}}},{"address":"aws_launch_configuration.my_web_config","mode":"managed","type":"aws_launch_configuration","name":"my_web_config","provider_name":"aws","change":{"actions":["create"],"before":null,"after":{"associate_public_ip_address":false,"enable_monitoring":true,"ephemeral_block_device":[],"iam_instance_profile":null,"image_id":"ami-09b4b74c","instance_type":"t2.micro","name":"my_web_config","name_prefix":null,"placement_tenancy":null,"security_groups":null,"spot_price":null,"user_data":null,"user_data_base64":null,"vpc_classic_link_id":null,"vpc_classic_link_security_groups":null},"after_unknown":{"ebs_block_device":true,"ebs_optimized":true,"ephemeral_block_device":[],"id":true,"key_name":true,"root_block_device":true}}}],"configuration":{"provider_config":{"aws":{"name":"aws","expressions":{"region":{"constant_value":"us-west-1"}}}},"root_module":{"resources":[{"address":"aws_autoscaling_group.my_asg","mode":"managed","type":"aws_autoscaling_group","name":"my_asg","provider_config_key":"aws","expressions":{"availability_zones":{"constant_value":["us-west-1a"]},"desired_capacity":{"constant_value":4},"force_delete":{"constant_value":true},"health_check_grace_period":{"constant_value":300},"health_check_type":{"constant_value":"ELB"},"launch_configuration":{"constant_value":"my_web_config"},"max_size":{"constant_value":5},"min_size":{"constant_value":1},"name":{"constant_value":"my_asg"}},"schema_version":0},{"address":"aws_instance.web","mode":"managed","type":"aws_instance","name":"web","provider_config_key":"aws","expressions":{"ami":{"constant_value":"ami-09b4b74c"},"instance_type":{"constant_value":"t2.micro"}},"schema_version":1},{"address":"aws_launch_configuration.my_web_config","mode":"managed","type":"aws_launch_configuration","name":"my_web_config","provider_config_key":"aws","expressions":{"image_id":{"constant_value":"ami-09b4b74c"},"instance_type":{"constant_value":"t2.micro"},"name":{"constant_value":"my_web_config"}},"schema_version":0}]}}}}`))) + req := httptest.NewRequest(http.MethodPost, `/plans`, bytes.NewReader([]byte(`{"lineage":"lineage_value","terraform_version":"1.0.0","git_remote":"foo.com","git_commit":"#12345","ci_url":"","source":"","exit_code":0,"plan_json":{"format_version":"0.1","terraform_version":"0.12.6","planned_values":{"root_module":{"resources":[{"address":"aws_autoscaling_group.my_asg","mode":"managed","type":"aws_autoscaling_group","name":"my_asg","provider_name":"aws","schema_version":0,"values":{"availability_zones":["us-west-1a"],"desired_capacity":4,"enabled_metrics":null,"force_delete":true,"health_check_grace_period":300,"health_check_type":"ELB","initial_lifecycle_hook":[],"launch_configuration":"my_web_config","launch_template":[],"max_size":5,"metrics_granularity":"1Minute","min_elb_capacity":null,"min_size":1,"mixed_instances_policy":[],"name":"my_asg","name_prefix":null,"placement_group":null,"protect_from_scale_in":false,"suspended_processes":null,"tag":[],"tags":null,"termination_policies":null,"timeouts":null,"wait_for_capacity_timeout":"10m","wait_for_elb_capacity":null}},{"address":"aws_instance.web","mode":"managed","type":"aws_instance","name":"web","provider_name":"aws","schema_version":1,"values":{"ami":"ami-09b4b74c","credit_specification":[],"disable_api_termination":null,"ebs_optimized":null,"get_password_data":false,"iam_instance_profile":null,"instance_initiated_shutdown_behavior":null,"instance_type":"t2.micro","monitoring":null,"source_dest_check":true,"tags":null,"timeouts":null,"user_data":null,"user_data_base64":null}},{"address":"aws_launch_configuration.my_web_config","mode":"managed","type":"aws_launch_configuration","name":"my_web_config","provider_name":"aws","schema_version":0,"values":{"associate_public_ip_address":false,"enable_monitoring":true,"ephemeral_block_device":[],"iam_instance_profile":null,"image_id":"ami-09b4b74c","instance_type":"t2.micro","name":"my_web_config","name_prefix":null,"placement_tenancy":null,"security_groups":null,"spot_price":null,"user_data":null,"user_data_base64":null,"vpc_classic_link_id":null,"vpc_classic_link_security_groups":null}}]}},"resource_changes":[{"address":"aws_autoscaling_group.my_asg","mode":"managed","type":"aws_autoscaling_group","name":"my_asg","provider_name":"aws","change":{"actions":["create"],"before":null,"after":{"availability_zones":["us-west-1a"],"desired_capacity":4,"enabled_metrics":null,"force_delete":true,"health_check_grace_period":300,"health_check_type":"ELB","initial_lifecycle_hook":[],"launch_configuration":"my_web_config","launch_template":[],"max_size":5,"metrics_granularity":"1Minute","min_elb_capacity":null,"min_size":1,"mixed_instances_policy":[],"name":"my_asg","name_prefix":null,"placement_group":null,"protect_from_scale_in":false,"suspended_processes":null,"tag":[],"tags":null,"termination_policies":null,"timeouts":null,"wait_for_capacity_timeout":"10m","wait_for_elb_capacity":null},"after_unknown":{"arn":true,"availability_zones":[false],"default_cooldown":true,"id":true,"initial_lifecycle_hook":[],"launch_template":[],"load_balancers":true,"mixed_instances_policy":[],"service_linked_role_arn":true,"tag":[],"target_group_arns":true,"vpc_zone_identifier":true}}},{"address":"aws_instance.web","mode":"managed","type":"aws_instance","name":"web","provider_name":"aws","change":{"actions":["create"],"before":null,"after":{"ami":"ami-09b4b74c","credit_specification":[],"disable_api_termination":null,"ebs_optimized":null,"get_password_data":false,"iam_instance_profile":null,"instance_initiated_shutdown_behavior":null,"instance_type":"t2.micro","monitoring":null,"source_dest_check":true,"tags":null,"timeouts":null,"user_data":null,"user_data_base64":null},"after_unknown":{"arn":true,"associate_public_ip_address":true,"availability_zone":true,"cpu_core_count":true,"cpu_threads_per_core":true,"credit_specification":[],"ebs_block_device":true,"ephemeral_block_device":true,"host_id":true,"id":true,"instance_state":true,"ipv6_address_count":true,"ipv6_addresses":true,"key_name":true,"network_interface":true,"network_interface_id":true,"password_data":true,"placement_group":true,"primary_network_interface_id":true,"private_dns":true,"private_ip":true,"public_dns":true,"public_ip":true,"root_block_device":true,"security_groups":true,"subnet_id":true,"tenancy":true,"volume_tags":true,"vpc_security_group_ids":true}}},{"address":"aws_launch_configuration.my_web_config","mode":"managed","type":"aws_launch_configuration","name":"my_web_config","provider_name":"aws","change":{"actions":["create"],"before":null,"after":{"associate_public_ip_address":false,"enable_monitoring":true,"ephemeral_block_device":[],"iam_instance_profile":null,"image_id":"ami-09b4b74c","instance_type":"t2.micro","name":"my_web_config","name_prefix":null,"placement_tenancy":null,"security_groups":null,"spot_price":null,"user_data":null,"user_data_base64":null,"vpc_classic_link_id":null,"vpc_classic_link_security_groups":null},"after_unknown":{"ebs_block_device":true,"ebs_optimized":true,"ephemeral_block_device":[],"id":true,"key_name":true,"root_block_device":true}}}],"configuration":{"provider_config":{"aws":{"name":"aws","expressions":{"region":{"constant_value":"us-west-1"}}}},"root_module":{"resources":[{"address":"aws_autoscaling_group.my_asg","mode":"managed","type":"aws_autoscaling_group","name":"my_asg","provider_config_key":"aws","expressions":{"availability_zones":{"constant_value":["us-west-1a"]},"desired_capacity":{"constant_value":4},"force_delete":{"constant_value":true},"health_check_grace_period":{"constant_value":300},"health_check_type":{"constant_value":"ELB"},"launch_configuration":{"constant_value":"my_web_config"},"max_size":{"constant_value":5},"min_size":{"constant_value":1},"name":{"constant_value":"my_asg"}},"schema_version":0},{"address":"aws_instance.web","mode":"managed","type":"aws_instance","name":"web","provider_config_key":"aws","expressions":{"ami":{"constant_value":"ami-09b4b74c"},"instance_type":{"constant_value":"t2.micro"}},"schema_version":1},{"address":"aws_launch_configuration.my_web_config","mode":"managed","type":"aws_launch_configuration","name":"my_web_config","provider_config_key":"aws","expressions":{"image_id":{"constant_value":"ami-09b4b74c"},"instance_type":{"constant_value":"t2.micro"},"name":{"constant_value":"my_web_config"}},"schema_version":0}]}}}}`))) ManagePlans(buf, req, db) if buf.Body.String() != `` { diff --git a/config/config.go b/config/config.go index 06c2b3fe..b80d6c90 100644 --- a/config/config.go +++ b/config/config.go @@ -98,9 +98,10 @@ type GitlabConfig struct { // WebConfig stores the UI interface parameters type WebConfig struct { - Port uint16 `short:"p" long:"port" env:"TERRABOARD_PORT" yaml:"port" description:"Port to listen on." default:"8080"` - BaseURL string `long:"base-url" env:"TERRABOARD_BASE_URL" yaml:"base-url" description:"Base URL." default:"/"` - LogoutURL string `long:"logout-url" env:"TERRABOARD_LOGOUT_URL" yaml:"logout-url" description:"Logout URL."` + Port uint16 `short:"p" long:"port" env:"TERRABOARD_PORT" yaml:"port" description:"Port to listen on." default:"8080"` + SwaggerPort uint16 `long:"swagger-port" env:"TERRABOARD_SWAGGER_PORT" yaml:"swagger-port" description:"Port for swagger to listen on." default:"8081"` + BaseURL string `long:"base-url" env:"TERRABOARD_BASE_URL" yaml:"base-url" description:"Base URL." default:"/"` + LogoutURL string `long:"logout-url" env:"TERRABOARD_LOGOUT_URL" yaml:"logout-url" description:"Logout URL."` } // ProviderConfig stores genral provider parameters diff --git a/config/config_test.go b/config/config_test.go index 0cbb0bd6..93f69c4b 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -75,9 +75,10 @@ func TestLoadConfig(t *testing.T) { }, }, Web: WebConfig{ - Port: 8080, - BaseURL: "/", - LogoutURL: "", + Port: 8080, + SwaggerPort: 8081, + BaseURL: "/", + LogoutURL: "", }, } @@ -142,9 +143,10 @@ func TestLoadConfigFromYaml(t *testing.T) { }, }, Web: WebConfig{ - Port: 39090, - BaseURL: "/test/", - LogoutURL: "/test-logout", + Port: 39090, + SwaggerPort: 8081, + BaseURL: "/test/", + LogoutURL: "/test-logout", }, } diff --git a/config/config_test.yml b/config/config_test.yml index 6f4610e5..0b3251a6 100644 --- a/config/config_test.yml +++ b/config/config_test.yml @@ -37,5 +37,6 @@ gitlab: web: port: 39090 + swagger-port: 8081 base-url: /test/ logout-url: /test-logout diff --git a/docs/docs.go b/docs/docs.go index dc00c2aa..1cf412af 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -504,6 +504,9 @@ var doc = `{ "ci_url": { "type": "string" }, + "exit_code": { + "type": "integer" + }, "git_commit": { "type": "string" }, diff --git a/docs/swagger.json b/docs/swagger.json index 8ef6bdbc..8bd22165 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -490,6 +490,9 @@ "ci_url": { "type": "string" }, + "exit_code": { + "type": "integer" + }, "git_commit": { "type": "string" }, diff --git a/docs/swagger.yaml b/docs/swagger.yaml index de737836..81a93108 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -4,6 +4,8 @@ definitions: properties: ci_url: type: string + exit_code: + type: integer git_commit: type: string git_remote: diff --git a/main.go b/main.go index 496e35cf..53ef69f8 100644 --- a/main.go +++ b/main.go @@ -206,14 +206,14 @@ func main() { // Handle swagger files swaggerRouter := mux.NewRouter() - swaggerRouter.HandleFunc("/swagger/", func(w http.ResponseWriter, r *http.Request) { + swaggerRouter.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "/swagger/index.html", http.StatusMovedPermanently) }) - swaggerRouter.PathPrefix("/swagger/").Handler(httpSwagger.Handler( + swaggerRouter.PathPrefix("/").Handler(httpSwagger.Handler( httpSwagger.URL("/swagger/doc.json"), )) swaggerRouter.Use(corsMiddleware) - go serveSwagger(8081, swaggerRouter) + go serveSwagger(int(c.Web.SwaggerPort), swaggerRouter) // Serve static files (CSS, JS, images) from dir spa := spaHandler{staticPath: "static", indexPath: "index.html"}