Merge branch 'master' into local-sudoer-without-pw
This commit is contained in:
commit
52641f8665
14 changed files with 114 additions and 125 deletions
|
@ -46,7 +46,7 @@ test:
|
|||
- docker build --pull -t "$CI_REGISTRY_IMAGE" .
|
||||
- docker run --privileged -dit --name provs_test -v /var/run/docker.sock:/var/run/docker.sock $CI_REGISTRY_IMAGE
|
||||
- docker inspect -f '{{.State.Running}}' provs_test
|
||||
- ./gradlew -x assemble test -Dtestdockerwithoutsudo=true -DexcludeTags=extensivecontainertest
|
||||
- ./gradlew -x assemble test -Dtestdockerwithoutsudo=true -DexcludeTags=extensivecontainertest,nonci
|
||||
artifacts:
|
||||
when: on_failure
|
||||
paths:
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
```plantuml
|
||||
@startuml
|
||||
|
||||
autonumber
|
||||
|
||||
skinparam sequenceBox {
|
||||
borderColor White
|
||||
}
|
||||
|
||||
participant User
|
||||
|
||||
box "application" #LightBlue
|
||||
|
||||
participant CliWorkplace
|
||||
participant CliWorkplaceParser
|
||||
participant CliWorkplaceCommand
|
||||
participant Application
|
||||
|
||||
end box
|
||||
|
||||
box #White
|
||||
|
||||
participant CliUtils
|
||||
participant "Prov (local or remote...)" as ProvInstance
|
||||
|
||||
end box
|
||||
|
||||
box "domain" #LightGreen
|
||||
|
||||
participant ProvisionWorkplace
|
||||
|
||||
end box
|
||||
|
||||
box "infrastructure" #CornSilk
|
||||
|
||||
participant ConfigRepository
|
||||
participant "Infrastructure functions" as Infrastructure_functions
|
||||
|
||||
end box
|
||||
|
||||
|
||||
User -> CliWorkplace ++ : main(args...)
|
||||
|
||||
CliWorkplace -> CliWorkplaceParser : parseWorkplaceArguments
|
||||
|
||||
CliWorkplace -> CliWorkplaceCommand : isValid ?
|
||||
|
||||
CliWorkplace -> ConfigRepository : getConfig
|
||||
|
||||
CliWorkplace -> CliUtils : createProvInstance
|
||||
ProvInstance <- CliUtils : create
|
||||
|
||||
CliWorkplace -> Application : provision ( config )
|
||||
Application -> ProvInstance : provisionWorkplace ( type, ssh, ...)
|
||||
ProvInstance -> ProvisionWorkplace : provisionWorkplace
|
||||
|
||||
ProvisionWorkplace -> Infrastructure_functions: Various calls like:
|
||||
ProvisionWorkplace -> Infrastructure_functions: install ssh, gpg, git ...
|
||||
ProvisionWorkplace -> Infrastructure_functions: installVirtualBoxGuestAdditions
|
||||
ProvisionWorkplace -> Infrastructure_functions: configureNoSwappiness, ...
|
||||
|
||||
@enduml
|
||||
```
|
39
doc/DesktopCliParsingSequence.md
Normal file
39
doc/DesktopCliParsingSequence.md
Normal file
|
@ -0,0 +1,39 @@
|
|||
```plantuml
|
||||
@startuml
|
||||
|
||||
autonumber
|
||||
|
||||
skinparam sequenceBox {
|
||||
borderColor White
|
||||
}
|
||||
|
||||
participant User
|
||||
|
||||
User -> Application ++ : main(args...)
|
||||
Application -> CliArgumentsParser : create
|
||||
CliArgumentsParser -> ArgParser : subcommands
|
||||
Application -> CliArgumentsParser : parseCommand
|
||||
CliArgumentsParser -> ArgParser : super.parse
|
||||
|
||||
CliArgumentsParser -> CliTargetCommand : create()
|
||||
CliTargetCommand -> CliTargetCommand : parseRemoteTarget
|
||||
alt passwordInteractive == true
|
||||
CliTargetCommand -> PromptSecretSource : prompt-for-password
|
||||
end
|
||||
CliArgumentsParser -> DesktopCliCommand : create(desktopType, cliTargetCmd, ...)
|
||||
CliArgumentsParser --> Application: desktopCliCommand
|
||||
Application -> DesktopCliCommand : isValid ?
|
||||
Application -> CliUtils : createProvInstance
|
||||
ProvInstance <- CliUtils : create
|
||||
alt target.isValidLocal
|
||||
CliUtils -> CliUtils : createLocalProv
|
||||
else target.isValidRemote
|
||||
CliUtils -> CliUtils : createRemote
|
||||
end
|
||||
Application -> DesktopService1 : provisionDesktopCommand ( provInstance, desktopCliCommand )
|
||||
DesktopService1 -> DesktopService2 : provisionDesktop( config )
|
||||
DesktopService1 -> ConfigRepository : getConfig
|
||||
|
||||
@enduml
|
||||
|
||||
```
|
|
@ -29,6 +29,6 @@ The success or failure is computed automatically in the following way:
|
|||
|
||||
## Call hierarchy
|
||||
|
||||
Find below an example of a sequence diagram when provisioning a desktop workplace:
|
||||
In the following link you can find an example of a sequence diagram when provisioning a desktop:
|
||||
|
||||
![img.png](resources/provision-workplace-sequence.diagram.png)
|
||||
[ProvisionDesktopSequence.md](ProvisionDesktopSequence.md)
|
||||
|
|
49
doc/ProvisionDesktopSequence.md
Normal file
49
doc/ProvisionDesktopSequence.md
Normal file
|
@ -0,0 +1,49 @@
|
|||
```plantuml
|
||||
@startuml
|
||||
|
||||
autonumber
|
||||
|
||||
skinparam sequenceBox {
|
||||
borderColor White
|
||||
}
|
||||
|
||||
participant User
|
||||
|
||||
box "application" #LightBlue
|
||||
participant Application
|
||||
participant CliArgumentsParser
|
||||
participant DesktopCliCommand
|
||||
end box
|
||||
|
||||
box #White
|
||||
participant CliUtils
|
||||
participant "Prov (local or remote...)" as ProvInstance
|
||||
end box
|
||||
|
||||
box "domain" #LightGreen
|
||||
participant "DesktopService\n.provisionDesktopCommand" as DesktopService1
|
||||
participant "DesktopService\n.provisionDesktop" as DesktopService2
|
||||
end box
|
||||
|
||||
box "infrastructure" #CornSilk
|
||||
participant ConfigRepository
|
||||
participant "Various\ninfrastructure functions" as Infrastructure_functions
|
||||
end box
|
||||
|
||||
|
||||
User -> Application ++ : main(args...)
|
||||
Application -> CliArgumentsParser : parseCommand
|
||||
Application -> DesktopCliCommand : isValid ?
|
||||
Application -> CliUtils : createProvInstance
|
||||
ProvInstance <- CliUtils : create
|
||||
Application -> DesktopService1 : provisionDesktopCommand ( provInstance, desktopCliCommand )
|
||||
DesktopService1 -> ConfigRepository : getConfig
|
||||
DesktopService1 -> DesktopService2 : provisionDesktop( config )
|
||||
|
||||
DesktopService2 -> Infrastructure_functions: Various calls like:
|
||||
DesktopService2 -> Infrastructure_functions: install ssh, gpg, git ...
|
||||
DesktopService2 -> Infrastructure_functions: installVirtualBoxGuestAdditions
|
||||
DesktopService2 -> Infrastructure_functions: configureNoSwappiness, ...
|
||||
|
||||
@enduml
|
||||
```
|
|
@ -28,45 +28,3 @@ In the following document we describe how we implement idempotence:
|
|||
|
||||
https://gitlab.com/domaindrivenarchitecture/overview/-/blob/master/adr-provs/quasi-idempotence.md
|
||||
|
||||
|
||||
## Architecture
|
||||
|
||||
Multiple architectural layers provide different levels of functionality:
|
||||
|
||||
![provs layers](resources/provs-architecture-7.png "Provs architecture")
|
||||
|
||||
|
||||
## Module structure
|
||||
|
||||
For the modules we use domain-drive design according to:
|
||||
|
||||
https://gitlab.com/domaindrivenarchitecture/overview/-/blob/master/adr-provs/ddd-structure.md
|
||||
|
||||
## Module dependencies
|
||||
|
||||
![resources/prov-module-dependencies-5b.png](resources/prov-module-dependencies-5b.png)
|
||||
|
||||
__Explanation__:
|
||||
|
||||
Modules:
|
||||
|
||||
<ol type="A">
|
||||
<li>Common module: has both a domain layer and an infrastructure layer</li>
|
||||
<li>Module with only domain layer: e.g. for very simple logic where no infrastructure layer is needed</li>
|
||||
<li>Module with only infrastructure layer: these are often _utility modules_, which provide a collection of utility functions</li>
|
||||
</ol>
|
||||
|
||||
Dependencies:
|
||||
|
||||
1. Domain layer calls (a function in) the infrastructure layer of the same module
|
||||
* _Common practice of dependencies within a module_
|
||||
1. Domain layer calls (a function in) the domain layer another module
|
||||
* _Common practice of dependencies between modules_
|
||||
1. Base layer calls domain layer
|
||||
* _Usually not recommended!_
|
||||
4. Domain layer calls infrastructure layer in another module
|
||||
* _This sometimes can make sense, e.g. if module B just needs some low-level function of module D instead of full provisioning.
|
||||
However, in most cases it is recommended to call the domain layer of module D whenever possible_
|
||||
5. Domain layer calls infrastructure layer in another module, which only has infrastructure layer
|
||||
* _Common practice for calling utility modules, which don't have a domain layer._
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 33 KiB |
Binary file not shown.
Before Width: | Height: | Size: 51 KiB |
Binary file not shown.
Before Width: | Height: | Size: 100 KiB |
|
@ -3,7 +3,6 @@ package org.domaindrivenarchitecture.provs.configuration.application
|
|||
import kotlinx.cli.ArgParser
|
||||
import kotlinx.cli.ArgType
|
||||
import kotlinx.cli.default
|
||||
import org.domaindrivenarchitecture.provs.configuration.domain.TargetCliCommand
|
||||
|
||||
open class CliTargetParser(name: String) : ArgParser(name) {
|
||||
val target by argument(
|
||||
|
@ -16,14 +15,4 @@ open class CliTargetParser(name: String) : ArgParser(name) {
|
|||
"p",
|
||||
"prompt for password for remote target",
|
||||
).default(false)
|
||||
}
|
||||
|
||||
fun parseTarget(
|
||||
programName: String = "provs",
|
||||
args: Array<String>
|
||||
): TargetCliCommand {
|
||||
val parser = CliTargetParser(programName)
|
||||
parser.parse(args)
|
||||
|
||||
return TargetCliCommand(parser.target, parser.passwordInteractive)
|
||||
}
|
|
@ -25,12 +25,14 @@ open class CliArgumentsParser(name: String) : CliTargetParser(name) {
|
|||
|
||||
val module = modules.first { it.parsed }
|
||||
|
||||
val targetCliCommand = TargetCliCommand(
|
||||
target,
|
||||
passwordInteractive
|
||||
)
|
||||
|
||||
return DesktopCliCommand(
|
||||
DesktopType.valueOf(module.name.uppercase()),
|
||||
TargetCliCommand(
|
||||
target,
|
||||
passwordInteractive
|
||||
),
|
||||
targetCliCommand,
|
||||
module.configFileName,
|
||||
module.onlyModules
|
||||
)
|
||||
|
|
|
@ -1,9 +1,21 @@
|
|||
package org.domaindrivenarchitecture.provs.configuration.application
|
||||
|
||||
import org.domaindrivenarchitecture.provs.configuration.domain.TargetCliCommand
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.Disabled
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
|
||||
private fun parseTarget(
|
||||
args: Array<String>
|
||||
): TargetCliCommand {
|
||||
val parser = CliTargetParser("provs")
|
||||
|
||||
parser.parse(args)
|
||||
|
||||
return TargetCliCommand(parser.target, parser.passwordInteractive)
|
||||
}
|
||||
|
||||
internal class CliTargetParserTest {
|
||||
|
||||
@Test
|
||||
|
|
|
@ -8,6 +8,7 @@ import org.domaindrivenarchitecture.provs.framework.core.cli.getPasswordToConfig
|
|||
import org.domaindrivenarchitecture.provs.framework.core.local
|
||||
import org.domaindrivenarchitecture.provs.framework.core.processors.PrintOnlyProcessor
|
||||
import org.domaindrivenarchitecture.provs.framework.core.remote
|
||||
import org.domaindrivenarchitecture.provs.test.tags.NonCi
|
||||
import org.junit.jupiter.api.AfterAll
|
||||
import org.junit.jupiter.api.BeforeAll
|
||||
import org.junit.jupiter.api.Test
|
||||
|
@ -39,6 +40,7 @@ internal class CliTargetCommandKtTest {
|
|||
|
||||
|
||||
@Test
|
||||
@NonCi
|
||||
fun createProvInstance_local() {
|
||||
// given
|
||||
val cliCommand = TargetCliCommand("local", false)
|
||||
|
|
|
@ -6,7 +6,7 @@ import org.junit.jupiter.api.Test
|
|||
|
||||
private const val CONTAINER_TEST = "containertest"
|
||||
private const val EXTENSIVE_CONTAINER_TEST = "extensivecontainertest"
|
||||
private const val CONTAINER_TEST_NON_CI = "containernonci"
|
||||
private const val NON_CI = "nonci"
|
||||
|
||||
|
||||
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
|
||||
|
@ -28,6 +28,7 @@ annotation class ExtensiveContainerTest
|
|||
|
||||
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
|
||||
@Retention
|
||||
@Tag(CONTAINER_TEST_NON_CI)
|
||||
@Tag(NON_CI)
|
||||
@Test
|
||||
// For test which do not run in ci pipeline
|
||||
annotation class NonCi
|
Loading…
Reference in a new issue