diff --git a/lib/cove/configuration/contracts/service_contract.rb b/lib/cove/configuration/contracts/service_contract.rb index 8fe1fca..758e67c 100644 --- a/lib/cove/configuration/contracts/service_contract.rb +++ b/lib/cove/configuration/contracts/service_contract.rb @@ -18,6 +18,13 @@ class ServiceContract < Dry::Validation::Contract required(:target).filled(:integer) end end + optional(:mounts).value(:array).each do + hash do + required(:type).value(eql?: "volume") + required(:source).filled(:string) + required(:target).filled(:string) + end + end end end end diff --git a/lib/cove/configuration/service.rb b/lib/cove/configuration/service.rb index 39459eb..f0b8919 100644 --- a/lib/cove/configuration/service.rb +++ b/lib/cove/configuration/service.rb @@ -64,7 +64,7 @@ def validate! def formatted_roles config["roles"].map do |role_name, role_config| - {name: role_name, container_count: role_config["container_count"], ingress: role_config["ingress"]}.compact + {name: role_name, container_count: role_config["container_count"], ingress: role_config["ingress"], mounts: role_config["mounts"]}.compact end end end diff --git a/spec/cove/configuration/contracts/service_contract_spec.rb b/spec/cove/configuration/contracts/service_contract_spec.rb index a5e718f..0f2e529 100644 --- a/spec/cove/configuration/contracts/service_contract_spec.rb +++ b/spec/cove/configuration/contracts/service_contract_spec.rb @@ -126,5 +126,41 @@ expect(result.success?).to eq(false) end end + + context "mounts" do + it "succeeds when mounts are included" do + contract = Cove::Configuration::Contracts::ServiceContract.new + result = contract.call(service_name: "a", image: "b", roles: [{name: "web", mounts: [{type: "volume", source: "my-awesome-volume", target: "/data"}]}]) + expect(result.success?).to eq(true) + end + + it "fails when type is invalid" do + contract = Cove::Configuration::Contracts::ServiceContract.new + result = contract.call(service_name: "a", image: "b", roles: [{name: "web", mounts: [{type: "foo", source: "my-awesome-volume", target: "/data"}]}]) + expect(result.errors[:roles][0][:mounts][0][:type]).to be_present + expect(result.success?).to eq(false) + end + + it "fails when type is not included" do + contract = Cove::Configuration::Contracts::ServiceContract.new + result = contract.call(service_name: "a", image: "b", roles: [{name: "web", mounts: [{source: "my-awesome-volume", target: "/data"}]}]) + expect(result.errors[:roles][0][:mounts][0][:type]).to be_present + expect(result.success?).to eq(false) + end + + it "fails when source is not included" do + contract = Cove::Configuration::Contracts::ServiceContract.new + result = contract.call(service_name: "a", image: "b", roles: [{name: "web", mounts: [{type: "volume", target: "/data"}]}]) + expect(result.errors[:roles][0][:mounts][0][:source]).to be_present + expect(result.success?).to eq(false) + end + + it "fails when target is not included" do + contract = Cove::Configuration::Contracts::ServiceContract.new + result = contract.call(service_name: "a", image: "b", roles: [{name: "web", mounts: [{type: "volume", source: "my-awesome-volume"}]}]) + expect(result.errors[:roles][0][:mounts][0][:target]).to be_present + expect(result.success?).to eq(false) + end + end end end