diff --git a/.github/workflows/auto-updates.yaml b/.github/workflows/auto-updates.yaml deleted file mode 100644 index ff4356351..000000000 --- a/.github/workflows/auto-updates.yaml +++ /dev/null @@ -1,94 +0,0 @@ -name: Update translation and Readme files in main branch automatically -on: - push: - branches: - - main - paths-ignore: - - po/* - - README.md - - debian/control - -env: - apt_dependencies: >- - ca-certificates curl dconf-cli gcc gettext git libnss-wrapper libsmbclient-dev - libwbclient-dev pkg-config protobuf-compiler python3-coverage samba sudo - -jobs: - update-po: - name: Update po files - runs-on: ubuntu-latest - steps: - # Checkout code with git - - uses: actions/checkout@v4 - with: - ref: main - - name: Update pot and po files - uses: ubuntu/go-i18n@main - with: - domain: "adsys" - entrypoints: "cmd/adsysd,cmd/admxgen,cmd/adwatchd" - - name: Check if there is a diff - id: po-diff - uses: canonical/desktop-engineering/gh-actions/common/has-diff@main - - name: Create Pull Request - if: ${{ steps.po-diff.outputs.diff == 'true' }} - uses: peter-evans/create-pull-request@v5 - with: - commit-message: Auto update po files - title: Auto update po files - labels: po, automated pr - body: "[Auto-generated pull request](https://github.com/ubuntu/adsys/actions/workflows/auto-updates.yaml) by GitHub Action" - branch: auto-update-po - token: ${{ secrets.GITHUB_TOKEN }} - - name: Push branch - if: ${{ steps.po-diff.outputs.diff == 'true' }} - run: | - git push origin auto-update-po:main - - update-readme-clid-ref: - name: Update readme and CLI ref files - # This should just be "after", but we don't want the 2 jobs to push at the same time - needs: update-po - runs-on: ubuntu-latest - steps: - - name: Install dependencies - run: | - sudo apt-get update - sudo DEBIAN_FRONTEND=noninteractive apt-get install -y ${{ env.apt_dependencies }} - # Checkout code with git - - uses: actions/checkout@v4 - with: - ref: main - # Install go - - uses: actions/setup-go@v4 - with: - go-version-file: go.mod - # Try updating README - - name: Check README file - id: checkreadme - run: | - set -eu - - hasModif="false" - cd cmd/adsysd - go run ../generate_completion_documentation.go update-readme - go run ../generate_completion_documentation.go update-doc-cli-ref - MODIFIED=$(git status --porcelain --untracked-files=no) - if [ -n "$MODIFIED" ]; then - hasModif="true" - fi - echo "modified=${hasModif}" >> $GITHUB_ENV - - name: Create Pull Request - if: ${{ env.modified == 'true' }} - uses: peter-evans/create-pull-request@v5 - with: - commit-message: Auto update readme files - title: Auto update readme files - labels: readme, automated pr - body: "[Auto-generated pull request](https://github.com/ubuntu/adsys/actions/workflows/auto-updates.yaml) by GitHub Action" - branch: auto-update-readme-cli-ref - token: ${{ secrets.GITHUB_TOKEN }} - - name: Push branch - if: ${{ env.modified == 'true' }} - run: | - git push origin auto-update-readme-cli-ref:main diff --git a/.github/workflows/automatic-doc-checks.yml b/.github/workflows/automatic-doc-checks.yml new file mode 100644 index 000000000..b7e76c762 --- /dev/null +++ b/.github/workflows/automatic-doc-checks.yml @@ -0,0 +1,16 @@ +name: Main Documentation Checks + +on: + - push + - pull_request + - workflow_dispatch + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + documentation-checks: + uses: canonical/documentation-workflows/.github/workflows/documentation-checks.yaml@main + with: + working-directory: 'docs/' diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 4009c66d7..000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "go.lintTool":"golangci-lint", - "go.lintFlags": [ - "--fast" - ] -} \ No newline at end of file diff --git a/README.md b/README.md index 13dfc5a49..66e703997 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # adsys -Active Directory bridging toolset + +Active Directory GPO support. [![Code quality](https://github.com/ubuntu/adsys/workflows/QA/badge.svg)](https://github.com/ubuntu/adsys/actions?query=workflow%3AQA) [![Code coverage](https://codecov.io/gh/ubuntu/adsys/branch/master/graph/badge.svg)](https://codecov.io/gh/ubuntu/adsys) @@ -7,1388 +8,9 @@ Active Directory bridging toolset [![Go Report Card](https://goreportcard.com/badge/ubuntu/adsys)](https://goreportcard.com/report/ubuntu/adsys) [![License](https://img.shields.io/badge/License-GPL3.0-blue.svg)](https://github.com/ubuntu/adsys/blob/master/LICENSE) -## Usage - -### User commands - -#### adsysctl - -AD integration client - -##### Synopsis - -Active Directory integration bridging toolset command line tool. - -``` -adsysctl COMMAND [flags] -``` - -##### Options - -``` - -c, --config string use a specific configuration file - -h, --help help for adsysctl - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl applied - -Print last applied GPOs for current or given user/machine - -##### Synopsis - -Alias of "policy applied" - -``` -adsysctl applied [USER_NAME] [flags] -``` - -##### Options - -``` - -a, --all show overridden rules in each GPOs. - --details show applied rules in addition to GPOs. - -h, --help help for applied - -m, --machine show applied rules to the machine. - --no-color don't display colorized version. -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl completion - -Generate the autocompletion script for the specified shell - -##### Synopsis - -Generate the autocompletion script for adsysctl for the specified shell. -See each sub-command's help for details on how to use the generated script. - - -##### Options - -``` - -h, --help help for completion -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl completion bash - -Generate the autocompletion script for bash - -##### Synopsis - -Generate the autocompletion script for the bash shell. - -This script depends on the 'bash-completion' package. -If it is not installed already, you can install it via your OS's package manager. - -To load completions in your current shell session: - - source <(adsysctl completion bash) - -To load completions for every new session, execute once: - -###### Linux: - - adsysctl completion bash > /etc/bash_completion.d/adsysctl - -###### macOS: - - adsysctl completion bash > $(brew --prefix)/etc/bash_completion.d/adsysctl - -You will need to start a new shell for this setup to take effect. - - -``` -adsysctl completion bash -``` - -##### Options - -``` - -h, --help help for bash - --no-descriptions disable completion descriptions -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl completion fish - -Generate the autocompletion script for fish - -##### Synopsis - -Generate the autocompletion script for the fish shell. - -To load completions in your current shell session: - - adsysctl completion fish | source - -To load completions for every new session, execute once: - - adsysctl completion fish > ~/.config/fish/completions/adsysctl.fish - -You will need to start a new shell for this setup to take effect. - - -``` -adsysctl completion fish [flags] -``` - -##### Options - -``` - -h, --help help for fish - --no-descriptions disable completion descriptions -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl completion powershell - -Generate the autocompletion script for powershell - -##### Synopsis - -Generate the autocompletion script for powershell. - -To load completions in your current shell session: - - adsysctl completion powershell | Out-String | Invoke-Expression - -To load completions for every new session, add the output of the above command -to your powershell profile. - - -``` -adsysctl completion powershell [flags] -``` - -##### Options - -``` - -h, --help help for powershell - --no-descriptions disable completion descriptions -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl completion zsh - -Generate the autocompletion script for zsh - -##### Synopsis - -Generate the autocompletion script for the zsh shell. - -If shell completion is not already enabled in your environment you will need -to enable it. You can execute the following once: - - echo "autoload -U compinit; compinit" >> ~/.zshrc - -To load completions in your current shell session: - - source <(adsysctl completion zsh) - -To load completions for every new session, execute once: - -###### Linux: - - adsysctl completion zsh > "${fpath[1]}/_adsysctl" - -###### macOS: - - adsysctl completion zsh > $(brew --prefix)/share/zsh/site-functions/_adsysctl - -You will need to start a new shell for this setup to take effect. - - -``` -adsysctl completion zsh [flags] -``` - -##### Options - -``` - -h, --help help for zsh - --no-descriptions disable completion descriptions -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl doc - -Documentation - -``` -adsysctl doc [CHAPTER] [flags] -``` - -##### Options - -``` - -d, --dest string Write documentation file(s) to this directory. - -f, --format string Format type (markdown, raw or html). (default "markdown") - -h, --help help for doc -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl policy - -Policy management - -``` -adsysctl policy COMMAND [flags] -``` - -##### Options - -``` - -h, --help help for policy -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl policy admx - -Dump windows policy definitions - -``` -adsysctl policy admx lts-only|all [flags] -``` - -##### Options - -``` - --distro string distro for which to retrieve policy definition. (default "Ubuntu") - -h, --help help for admx -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl policy applied - -Print last applied GPOs for current or given user/machine - -``` -adsysctl policy applied [USER_NAME] [flags] -``` - -##### Options - -``` - -a, --all show overridden rules in each GPOs. - --details show applied rules in addition to GPOs. - -h, --help help for applied - -m, --machine show applied rules to the machine. - --no-color don't display colorized version. -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl policy purge - -Purges policies for the current user or a specified one - -``` -adsysctl policy purge [USER_NAME] [flags] -``` - -##### Options - -``` - -a, --all all purges the policy of the computer and all the logged in users. -m or USER_NAME cannot be used with this option. - -h, --help help for purge - -m, --machine machine purges the policy of the computer. -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl policy update - -Updates/Create a policy for current user or given user with its kerberos ticket - -``` -adsysctl policy update [USER_NAME KERBEROS_TICKET_PATH] [flags] -``` - -##### Options - -``` - -a, --all all updates the policy of the computer and all the logged in users. -m or USER_NAME/TICKET cannot be used with this option. - -h, --help help for update - -m, --machine machine updates the policy of the computer. -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl service - -Service management - -``` -adsysctl service COMMAND [flags] -``` - -##### Options - -``` - -h, --help help for service -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl service cat +## Documentation and Usage -Print service logs - -``` -adsysctl service cat [flags] -``` - -##### Options - -``` - -h, --help help for cat -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl service status - -Print service status - -``` -adsysctl service status [flags] -``` - -##### Options - -``` - -h, --help help for status -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl service stop - -Requests to stop the service once all connections are done - -``` -adsysctl service stop [flags] -``` - -##### Options - -``` - -f, --force force will shut it down immediately and drop existing connections. - -h, --help help for stop -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl update - -Updates/Create a policy for current user or given user with its kerberos ticket - -##### Synopsis - -Alias of "policy update" - -``` -adsysctl update [USER_NAME KERBEROS_TICKET_PATH] [flags] -``` - -##### Options - -``` - -a, --all all updates the policy of the computer and all the logged in users. -m or USER_NAME/TICKET cannot be used with this option. - -h, --help help for update - -m, --machine machine updates the policy of the computer. -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl version - -Returns version of client and service - -``` -adsysctl version [flags] -``` - -##### Options - -``` - -h, --help help for version -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysd - -AD integration daemon - -##### Synopsis - -Active Directory integration bridging toolset daemon. - -``` -adsysd COMMAND [flags] -``` - -##### Options - -``` - --ad-backend string Active Directory authentication backend (default "sssd") - --cache-dir string directory where ADsys caches GPOs downloads and policies. (default "/var/cache/adsys") - -c, --config string use a specific configuration file - -h, --help help for adsysd - --run-dir string directory where ADsys stores transient information erased on reboot. (default "/run/adsys") - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - --sssd.cache-dir string SSSd cache directory (default "/var/lib/sss/db") - --sssd.config string SSSd config file path (default "/etc/sssd/sssd.conf") - -t, --timeout int time in seconds without activity before the service exists. 0 for no timeout. (default 120) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysd completion - -Generate the autocompletion script for the specified shell - -##### Synopsis - -Generate the autocompletion script for adsysd for the specified shell. -See each sub-command's help for details on how to use the generated script. - - -##### Options - -``` - -h, --help help for completion -``` - -##### Options inherited from parent commands - -``` - --ad-backend string Active Directory authentication backend (default "sssd") - --cache-dir string directory where ADsys caches GPOs downloads and policies. (default "/var/cache/adsys") - -c, --config string use a specific configuration file - --run-dir string directory where ADsys stores transient information erased on reboot. (default "/run/adsys") - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - --sssd.cache-dir string SSSd cache directory (default "/var/lib/sss/db") - --sssd.config string SSSd config file path (default "/etc/sssd/sssd.conf") - -t, --timeout int time in seconds without activity before the service exists. 0 for no timeout. (default 120) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysd completion bash - -Generate the autocompletion script for bash - -##### Synopsis - -Generate the autocompletion script for the bash shell. - -This script depends on the 'bash-completion' package. -If it is not installed already, you can install it via your OS's package manager. - -To load completions in your current shell session: - - source <(adsysd completion bash) - -To load completions for every new session, execute once: - -###### Linux: - - adsysd completion bash > /etc/bash_completion.d/adsysd - -###### macOS: - - adsysd completion bash > $(brew --prefix)/etc/bash_completion.d/adsysd - -You will need to start a new shell for this setup to take effect. - - -``` -adsysd completion bash -``` - -##### Options - -``` - -h, --help help for bash - --no-descriptions disable completion descriptions -``` - -##### Options inherited from parent commands - -``` - --ad-backend string Active Directory authentication backend (default "sssd") - --cache-dir string directory where ADsys caches GPOs downloads and policies. (default "/var/cache/adsys") - -c, --config string use a specific configuration file - --run-dir string directory where ADsys stores transient information erased on reboot. (default "/run/adsys") - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - --sssd.cache-dir string SSSd cache directory (default "/var/lib/sss/db") - --sssd.config string SSSd config file path (default "/etc/sssd/sssd.conf") - -t, --timeout int time in seconds without activity before the service exists. 0 for no timeout. (default 120) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysd completion fish - -Generate the autocompletion script for fish - -##### Synopsis - -Generate the autocompletion script for the fish shell. - -To load completions in your current shell session: - - adsysd completion fish | source - -To load completions for every new session, execute once: - - adsysd completion fish > ~/.config/fish/completions/adsysd.fish - -You will need to start a new shell for this setup to take effect. - - -``` -adsysd completion fish [flags] -``` - -##### Options - -``` - -h, --help help for fish - --no-descriptions disable completion descriptions -``` - -##### Options inherited from parent commands - -``` - --ad-backend string Active Directory authentication backend (default "sssd") - --cache-dir string directory where ADsys caches GPOs downloads and policies. (default "/var/cache/adsys") - -c, --config string use a specific configuration file - --run-dir string directory where ADsys stores transient information erased on reboot. (default "/run/adsys") - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - --sssd.cache-dir string SSSd cache directory (default "/var/lib/sss/db") - --sssd.config string SSSd config file path (default "/etc/sssd/sssd.conf") - -t, --timeout int time in seconds without activity before the service exists. 0 for no timeout. (default 120) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysd completion powershell - -Generate the autocompletion script for powershell - -##### Synopsis - -Generate the autocompletion script for powershell. - -To load completions in your current shell session: - - adsysd completion powershell | Out-String | Invoke-Expression - -To load completions for every new session, add the output of the above command -to your powershell profile. - - -``` -adsysd completion powershell [flags] -``` - -##### Options - -``` - -h, --help help for powershell - --no-descriptions disable completion descriptions -``` - -##### Options inherited from parent commands - -``` - --ad-backend string Active Directory authentication backend (default "sssd") - --cache-dir string directory where ADsys caches GPOs downloads and policies. (default "/var/cache/adsys") - -c, --config string use a specific configuration file - --run-dir string directory where ADsys stores transient information erased on reboot. (default "/run/adsys") - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - --sssd.cache-dir string SSSd cache directory (default "/var/lib/sss/db") - --sssd.config string SSSd config file path (default "/etc/sssd/sssd.conf") - -t, --timeout int time in seconds without activity before the service exists. 0 for no timeout. (default 120) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysd completion zsh - -Generate the autocompletion script for zsh - -##### Synopsis - -Generate the autocompletion script for the zsh shell. - -If shell completion is not already enabled in your environment you will need -to enable it. You can execute the following once: - - echo "autoload -U compinit; compinit" >> ~/.zshrc - -To load completions in your current shell session: - - source <(adsysd completion zsh) - -To load completions for every new session, execute once: - -###### Linux: - - adsysd completion zsh > "${fpath[1]}/_adsysd" - -###### macOS: - - adsysd completion zsh > $(brew --prefix)/share/zsh/site-functions/_adsysd - -You will need to start a new shell for this setup to take effect. - - -``` -adsysd completion zsh [flags] -``` - -##### Options - -``` - -h, --help help for zsh - --no-descriptions disable completion descriptions -``` - -##### Options inherited from parent commands - -``` - --ad-backend string Active Directory authentication backend (default "sssd") - --cache-dir string directory where ADsys caches GPOs downloads and policies. (default "/var/cache/adsys") - -c, --config string use a specific configuration file - --run-dir string directory where ADsys stores transient information erased on reboot. (default "/run/adsys") - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - --sssd.cache-dir string SSSd cache directory (default "/var/lib/sss/db") - --sssd.config string SSSd config file path (default "/etc/sssd/sssd.conf") - -t, --timeout int time in seconds without activity before the service exists. 0 for no timeout. (default 120) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysd version - -Returns version of service and exits - -``` -adsysd version [flags] -``` - -##### Options - -``` - -h, --help help for version -``` - -##### Options inherited from parent commands - -``` - --ad-backend string Active Directory authentication backend (default "sssd") - --cache-dir string directory where ADsys caches GPOs downloads and policies. (default "/var/cache/adsys") - -c, --config string use a specific configuration file - --run-dir string directory where ADsys stores transient information erased on reboot. (default "/run/adsys") - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - --sssd.cache-dir string SSSd cache directory (default "/var/lib/sss/db") - --sssd.config string SSSd config file path (default "/etc/sssd/sssd.conf") - -t, --timeout int time in seconds without activity before the service exists. 0 for no timeout. (default 120) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adwatchd - -AD watch daemon - -##### Synopsis - -Watch directories for changes and bump the relevant GPT.ini versions. - -``` -adwatchd [COMMAND] [flags] -``` - -##### Options - -``` - -c, --config string use a specific configuration file - -h, --help help for adwatchd - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adwatchd completion - -Generate the autocompletion script for the specified shell - -##### Synopsis - -Generate the autocompletion script for adwatchd for the specified shell. -See each sub-command's help for details on how to use the generated script. - - -##### Options - -``` - -h, --help help for completion -``` - -##### Options inherited from parent commands - -``` - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adwatchd completion bash - -Generate the autocompletion script for bash - -##### Synopsis - -Generate the autocompletion script for the bash shell. - -This script depends on the 'bash-completion' package. -If it is not installed already, you can install it via your OS's package manager. - -To load completions in your current shell session: - - source <(adwatchd completion bash) - -To load completions for every new session, execute once: - -###### Linux: - - adwatchd completion bash > /etc/bash_completion.d/adwatchd - -###### macOS: - - adwatchd completion bash > $(brew --prefix)/etc/bash_completion.d/adwatchd - -You will need to start a new shell for this setup to take effect. - - -``` -adwatchd completion bash -``` - -##### Options - -``` - -h, --help help for bash - --no-descriptions disable completion descriptions -``` - -##### Options inherited from parent commands - -``` - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adwatchd completion fish - -Generate the autocompletion script for fish - -##### Synopsis - -Generate the autocompletion script for the fish shell. - -To load completions in your current shell session: - - adwatchd completion fish | source - -To load completions for every new session, execute once: - - adwatchd completion fish > ~/.config/fish/completions/adwatchd.fish - -You will need to start a new shell for this setup to take effect. - - -``` -adwatchd completion fish [flags] -``` - -##### Options - -``` - -h, --help help for fish - --no-descriptions disable completion descriptions -``` - -##### Options inherited from parent commands - -``` - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adwatchd completion powershell - -Generate the autocompletion script for powershell - -##### Synopsis - -Generate the autocompletion script for powershell. - -To load completions in your current shell session: - - adwatchd completion powershell | Out-String | Invoke-Expression - -To load completions for every new session, add the output of the above command -to your powershell profile. - - -``` -adwatchd completion powershell [flags] -``` - -##### Options - -``` - -h, --help help for powershell - --no-descriptions disable completion descriptions -``` - -##### Options inherited from parent commands - -``` - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adwatchd completion zsh - -Generate the autocompletion script for zsh - -##### Synopsis - -Generate the autocompletion script for the zsh shell. - -If shell completion is not already enabled in your environment you will need -to enable it. You can execute the following once: - - echo "autoload -U compinit; compinit" >> ~/.zshrc - -To load completions in your current shell session: - - source <(adwatchd completion zsh) - -To load completions for every new session, execute once: - -###### Linux: - - adwatchd completion zsh > "${fpath[1]}/_adwatchd" - -###### macOS: - - adwatchd completion zsh > $(brew --prefix)/share/zsh/site-functions/_adwatchd - -You will need to start a new shell for this setup to take effect. - - -``` -adwatchd completion zsh [flags] -``` - -##### Options - -``` - -h, --help help for zsh - --no-descriptions disable completion descriptions -``` - -##### Options inherited from parent commands - -``` - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adwatchd run - -Starts the directory watch loop - -##### Synopsis - -Can run as a service through the service manager or interactively as a standalone application. - -The program will monitor the configured directories for changes and bump the appropriate GPT.ini versions anytime a change is detected. -If a GPT.ini file does not exist for a directory, a warning will be issued and the file will be created. If the GPT.ini file is incompatible or malformed, the program will report an error. - - -``` -adwatchd run [flags] -``` - -##### Options - -``` - -c, --config string use a specific configuration file - -d, --dirs directory a directory to check for changes (can be specified multiple times) - -f, --force force the program to run even if another instance is already running - -h, --help help for run -``` - -##### Options inherited from parent commands - -``` - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adwatchd service - -Manages the adwatchd service - -##### Synopsis - -The service command allows the user to interact with the adwatchd service. It can manage and query the service status, and also install and uninstall the service. - -``` -adwatchd service COMMAND [flags] -``` - -##### Options - -``` - -h, --help help for service -``` - -##### Options inherited from parent commands - -``` - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adwatchd service install - -Installs the service - -##### Synopsis - -Installs the adwatchd service. - -The service will be installed as a Windows service. - - -``` -adwatchd service install [flags] -``` - -##### Options - -``` - -c, --config string use a specific configuration file - -h, --help help for install -``` - -##### Options inherited from parent commands - -``` - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adwatchd service restart - -Restarts the service - -##### Synopsis - -Restarts the adwatchd service. - -``` -adwatchd service restart [flags] -``` - -##### Options - -``` - -h, --help help for restart -``` - -##### Options inherited from parent commands - -``` - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adwatchd service start - -Starts the service - -##### Synopsis - -Starts the adwatchd service. - -``` -adwatchd service start [flags] -``` - -##### Options - -``` - -h, --help help for start -``` - -##### Options inherited from parent commands - -``` - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adwatchd service status - -Returns service status - -##### Synopsis - -Returns the status of the adwatchd service. - -``` -adwatchd service status [flags] -``` - -##### Options - -``` - -h, --help help for status -``` - -##### Options inherited from parent commands - -``` - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adwatchd service stop - -Stops the service - -##### Synopsis - -Stops the adwatchd service. - -``` -adwatchd service stop [flags] -``` - -##### Options - -``` - -h, --help help for stop -``` - -##### Options inherited from parent commands - -``` - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adwatchd service uninstall - -Uninstalls the service - -##### Synopsis - -Uninstalls the adwatchd service. - -``` -adwatchd service uninstall [flags] -``` - -##### Options - -``` - -h, --help help for uninstall -``` - -##### Options inherited from parent commands - -``` - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adwatchd version - -Returns version of service and exits - -``` -adwatchd version [flags] -``` - -##### Options - -``` - -h, --help help for version -``` - -##### Options inherited from parent commands - -``` - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -### Hidden commands - -Those commands are hidden from help and should primarily be used by the system or for debugging. - -#### adsysctl policy debug - -Debug various policy infos - -``` -adsysctl policy debug [flags] -``` - -##### Options - -``` - -h, --help help for debug -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl policy debug cert-autoenroll-script - -Write certificate autoenrollment python embedded script in current directory - -``` -adsysctl policy debug cert-autoenroll-script [flags] -``` - -##### Options - -``` - -h, --help help for cert-autoenroll-script -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl policy debug gpolist-script - -Write GPO list python embeeded script in current directory - -``` -adsysctl policy debug gpolist-script [flags] -``` - -##### Options - -``` - -h, --help help for gpolist-script -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysd mount - -Mount the locations listed in the specified file for the current user - -``` -adsysd mount MOUNTS_FILE [flags] -``` - -##### Options - -``` - -h, --help help for mount -``` - -##### Options inherited from parent commands - -``` - --ad-backend string Active Directory authentication backend (default "sssd") - --cache-dir string directory where ADsys caches GPOs downloads and policies. (default "/var/cache/adsys") - -c, --config string use a specific configuration file - --run-dir string directory where ADsys stores transient information erased on reboot. (default "/run/adsys") - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - --sssd.cache-dir string SSSd cache directory (default "/var/lib/sss/db") - --sssd.config string SSSd config file path (default "/etc/sssd/sssd.conf") - -t, --timeout int time in seconds without activity before the service exists. 0 for no timeout. (default 120) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysd runscripts - -Runs scripts in the given subdirectory - -``` -adsysd runscripts ORDER_FILE [flags] -``` - -##### Options - -``` - --allow-order-missing allow ORDER_FILE to be missing once the scripts are ready. - -h, --help help for runscripts -``` - -##### Options inherited from parent commands - -``` - --ad-backend string Active Directory authentication backend (default "sssd") - --cache-dir string directory where ADsys caches GPOs downloads and policies. (default "/var/cache/adsys") - -c, --config string use a specific configuration file - --run-dir string directory where ADsys stores transient information erased on reboot. (default "/run/adsys") - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - --sssd.cache-dir string SSSd cache directory (default "/var/lib/sss/db") - --sssd.config string SSSd config file path (default "/etc/sssd/sssd.conf") - -t, --timeout int time in seconds without activity before the service exists. 0 for no timeout. (default 120) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` +Command line reference is available on [Read The Docs](https://canonical-adsys.readthedocs-hosted.com/en/latest/). ## Installing development versions diff --git a/adsys.pb.go b/adsys.pb.go index 9a5ddae6e..45b7065da 100644 --- a/adsys.pb.go +++ b/adsys.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.29.1 +// protoc-gen-go v1.31.0 // protoc v3.21.12 // source: adsys.proto @@ -506,16 +506,16 @@ func (x *GetDocRequest) GetChapter() string { return "" } -type ListDocRequest struct { +type ListDocReponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Raw bool `protobuf:"varint,1,opt,name=raw,proto3" json:"raw,omitempty"` // Set to true to not format the output of the table of content + Chapters []string `protobuf:"bytes,1,rep,name=chapters,proto3" json:"chapters,omitempty"` } -func (x *ListDocRequest) Reset() { - *x = ListDocRequest{} +func (x *ListDocReponse) Reset() { + *x = ListDocReponse{} if protoimpl.UnsafeEnabled { mi := &file_adsys_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -523,13 +523,13 @@ func (x *ListDocRequest) Reset() { } } -func (x *ListDocRequest) String() string { +func (x *ListDocReponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ListDocRequest) ProtoMessage() {} +func (*ListDocReponse) ProtoMessage() {} -func (x *ListDocRequest) ProtoReflect() protoreflect.Message { +func (x *ListDocReponse) ProtoReflect() protoreflect.Message { mi := &file_adsys_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -541,16 +541,16 @@ func (x *ListDocRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ListDocRequest.ProtoReflect.Descriptor instead. -func (*ListDocRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use ListDocReponse.ProtoReflect.Descriptor instead. +func (*ListDocReponse) Descriptor() ([]byte, []int) { return file_adsys_proto_rawDescGZIP(), []int{9} } -func (x *ListDocRequest) GetRaw() bool { +func (x *ListDocReponse) GetChapters() []string { if x != nil { - return x.Raw + return x.Chapters } - return false + return nil } var File_adsys_proto protoreflect.FileDescriptor @@ -593,49 +593,49 @@ var file_adsys_proto_rawDesc = []byte{ 0x12, 0x0a, 0x04, 0x61, 0x64, 0x6d, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x64, 0x6d, 0x6c, 0x22, 0x29, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x44, 0x6f, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x70, 0x74, 0x65, 0x72, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x70, 0x74, 0x65, 0x72, 0x22, 0x22, - 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x6f, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x10, 0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x72, - 0x61, 0x77, 0x32, 0xc9, 0x04, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x20, - 0x0a, 0x03, 0x43, 0x61, 0x74, 0x12, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0f, 0x2e, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x70, 0x74, 0x65, 0x72, 0x22, 0x2c, + 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x6f, 0x63, 0x52, 0x65, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x70, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x08, 0x63, 0x68, 0x61, 0x70, 0x74, 0x65, 0x72, 0x73, 0x32, 0xc0, 0x04, 0x0a, + 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x20, 0x0a, 0x03, 0x43, 0x61, 0x74, 0x12, + 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0f, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x24, 0x0a, 0x07, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0f, 0x2e, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, + 0x12, 0x23, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x06, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x1a, 0x0f, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x1e, 0x0a, 0x04, 0x53, 0x74, 0x6f, 0x70, 0x12, 0x0c, 0x2e, + 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x06, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x30, 0x01, 0x12, 0x2e, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x14, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x06, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x30, 0x01, 0x12, 0x37, 0x0a, 0x0c, 0x44, 0x75, 0x6d, 0x70, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x14, 0x2e, 0x44, 0x75, 0x6d, 0x70, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x53, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x5a, + 0x0a, 0x17, 0x44, 0x75, 0x6d, 0x70, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x44, 0x65, + 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1d, 0x2e, 0x44, 0x75, 0x6d, 0x70, + 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x44, 0x75, 0x6d, 0x70, 0x50, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x2b, 0x0a, 0x06, 0x47, 0x65, + 0x74, 0x44, 0x6f, 0x63, 0x12, 0x0e, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x6f, 0x63, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x24, 0x0a, 0x07, 0x4c, 0x69, 0x73, 0x74, 0x44, + 0x6f, 0x63, 0x12, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0f, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x44, 0x6f, 0x63, 0x52, 0x65, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x31, 0x0a, + 0x09, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x11, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, - 0x12, 0x24, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x06, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x1a, 0x0f, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x23, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0f, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x1e, 0x0a, 0x04, 0x53, - 0x74, 0x6f, 0x70, 0x12, 0x0c, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x30, 0x01, 0x12, 0x2e, 0x0a, 0x0c, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x14, 0x2e, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x30, 0x01, 0x12, 0x37, 0x0a, 0x0c, 0x44, - 0x75, 0x6d, 0x70, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x14, 0x2e, 0x44, 0x75, - 0x6d, 0x70, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x0f, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x30, 0x01, 0x12, 0x5a, 0x0a, 0x17, 0x44, 0x75, 0x6d, 0x70, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x69, 0x65, 0x73, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, - 0x1d, 0x2e, 0x44, 0x75, 0x6d, 0x70, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x44, 0x65, 0x66, 0x69, - 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, - 0x2e, 0x44, 0x75, 0x6d, 0x70, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x44, 0x65, 0x66, 0x69, 0x6e, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, - 0x12, 0x2b, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x44, 0x6f, 0x63, 0x12, 0x0e, 0x2e, 0x47, 0x65, 0x74, - 0x44, 0x6f, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x53, 0x74, 0x72, - 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x2d, 0x0a, - 0x07, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x6f, 0x63, 0x12, 0x0f, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, - 0x6f, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x53, 0x74, 0x72, 0x69, - 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x31, 0x0a, 0x09, - 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x11, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x53, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, - 0x2a, 0x0a, 0x0d, 0x47, 0x50, 0x4f, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x12, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0f, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x31, 0x0a, 0x14, 0x43, - 0x65, 0x72, 0x74, 0x41, 0x75, 0x74, 0x6f, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x12, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0f, 0x2e, 0x53, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x42, 0x19, - 0x5a, 0x17, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x62, 0x75, - 0x6e, 0x74, 0x75, 0x2f, 0x61, 0x64, 0x73, 0x79, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x12, 0x2a, 0x0a, 0x0d, 0x47, 0x50, 0x4f, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x12, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0f, 0x2e, 0x53, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x31, 0x0a, 0x14, + 0x43, 0x65, 0x72, 0x74, 0x41, 0x75, 0x74, 0x6f, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x12, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0f, 0x2e, 0x53, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x42, + 0x19, 0x5a, 0x17, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x62, + 0x75, 0x6e, 0x74, 0x75, 0x2f, 0x61, 0x64, 0x73, 0x79, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -661,7 +661,7 @@ var file_adsys_proto_goTypes = []interface{}{ (*DumpPolicyDefinitionsRequest)(nil), // 6: DumpPolicyDefinitionsRequest (*DumpPolicyDefinitionsResponse)(nil), // 7: DumpPolicyDefinitionsResponse (*GetDocRequest)(nil), // 8: GetDocRequest - (*ListDocRequest)(nil), // 9: ListDocRequest + (*ListDocReponse)(nil), // 9: ListDocReponse } var file_adsys_proto_depIdxs = []int32{ 0, // 0: service.Cat:input_type -> Empty @@ -672,7 +672,7 @@ var file_adsys_proto_depIdxs = []int32{ 5, // 5: service.DumpPolicies:input_type -> DumpPoliciesRequest 6, // 6: service.DumpPoliciesDefinitions:input_type -> DumpPolicyDefinitionsRequest 8, // 7: service.GetDoc:input_type -> GetDocRequest - 9, // 8: service.ListDoc:input_type -> ListDocRequest + 0, // 8: service.ListDoc:input_type -> Empty 1, // 9: service.ListUsers:input_type -> ListUsersRequest 0, // 10: service.GPOListScript:input_type -> Empty 0, // 11: service.CertAutoEnrollScript:input_type -> Empty @@ -684,7 +684,7 @@ var file_adsys_proto_depIdxs = []int32{ 3, // 17: service.DumpPolicies:output_type -> StringResponse 7, // 18: service.DumpPoliciesDefinitions:output_type -> DumpPolicyDefinitionsResponse 3, // 19: service.GetDoc:output_type -> StringResponse - 3, // 20: service.ListDoc:output_type -> StringResponse + 9, // 20: service.ListDoc:output_type -> ListDocReponse 3, // 21: service.ListUsers:output_type -> StringResponse 3, // 22: service.GPOListScript:output_type -> StringResponse 3, // 23: service.CertAutoEnrollScript:output_type -> StringResponse @@ -810,7 +810,7 @@ func file_adsys_proto_init() { } } file_adsys_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListDocRequest); i { + switch v := v.(*ListDocReponse); i { case 0: return &v.state case 1: diff --git a/adsys.proto b/adsys.proto index 307b28ca5..28e062f43 100644 --- a/adsys.proto +++ b/adsys.proto @@ -11,7 +11,7 @@ service service { rpc DumpPolicies(DumpPoliciesRequest) returns (stream StringResponse); rpc DumpPoliciesDefinitions(DumpPolicyDefinitionsRequest) returns (stream DumpPolicyDefinitionsResponse); rpc GetDoc(GetDocRequest) returns (stream StringResponse); - rpc ListDoc(ListDocRequest) returns (stream StringResponse); + rpc ListDoc(Empty) returns (stream ListDocReponse); rpc ListUsers(ListUsersRequest) returns (stream StringResponse); rpc GPOListScript(Empty) returns (stream StringResponse); rpc CertAutoEnrollScript(Empty) returns (stream StringResponse); @@ -60,6 +60,6 @@ message GetDocRequest { string chapter = 1; } -message ListDocRequest { - bool raw = 1; // Set to true to not format the output of the table of content -} +message ListDocReponse { + repeated string chapters = 1; +} \ No newline at end of file diff --git a/adsys_grpc.pb.go b/adsys_grpc.pb.go index 1bc7b2b16..75af5bcc5 100644 --- a/adsys_grpc.pb.go +++ b/adsys_grpc.pb.go @@ -45,7 +45,7 @@ type ServiceClient interface { DumpPolicies(ctx context.Context, in *DumpPoliciesRequest, opts ...grpc.CallOption) (Service_DumpPoliciesClient, error) DumpPoliciesDefinitions(ctx context.Context, in *DumpPolicyDefinitionsRequest, opts ...grpc.CallOption) (Service_DumpPoliciesDefinitionsClient, error) GetDoc(ctx context.Context, in *GetDocRequest, opts ...grpc.CallOption) (Service_GetDocClient, error) - ListDoc(ctx context.Context, in *ListDocRequest, opts ...grpc.CallOption) (Service_ListDocClient, error) + ListDoc(ctx context.Context, in *Empty, opts ...grpc.CallOption) (Service_ListDocClient, error) ListUsers(ctx context.Context, in *ListUsersRequest, opts ...grpc.CallOption) (Service_ListUsersClient, error) GPOListScript(ctx context.Context, in *Empty, opts ...grpc.CallOption) (Service_GPOListScriptClient, error) CertAutoEnrollScript(ctx context.Context, in *Empty, opts ...grpc.CallOption) (Service_CertAutoEnrollScriptClient, error) @@ -315,7 +315,7 @@ func (x *serviceGetDocClient) Recv() (*StringResponse, error) { return m, nil } -func (c *serviceClient) ListDoc(ctx context.Context, in *ListDocRequest, opts ...grpc.CallOption) (Service_ListDocClient, error) { +func (c *serviceClient) ListDoc(ctx context.Context, in *Empty, opts ...grpc.CallOption) (Service_ListDocClient, error) { stream, err := c.cc.NewStream(ctx, &Service_ServiceDesc.Streams[8], Service_ListDoc_FullMethodName, opts...) if err != nil { return nil, err @@ -331,7 +331,7 @@ func (c *serviceClient) ListDoc(ctx context.Context, in *ListDocRequest, opts .. } type Service_ListDocClient interface { - Recv() (*StringResponse, error) + Recv() (*ListDocReponse, error) grpc.ClientStream } @@ -339,8 +339,8 @@ type serviceListDocClient struct { grpc.ClientStream } -func (x *serviceListDocClient) Recv() (*StringResponse, error) { - m := new(StringResponse) +func (x *serviceListDocClient) Recv() (*ListDocReponse, error) { + m := new(ListDocReponse) if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err } @@ -455,7 +455,7 @@ type ServiceServer interface { DumpPolicies(*DumpPoliciesRequest, Service_DumpPoliciesServer) error DumpPoliciesDefinitions(*DumpPolicyDefinitionsRequest, Service_DumpPoliciesDefinitionsServer) error GetDoc(*GetDocRequest, Service_GetDocServer) error - ListDoc(*ListDocRequest, Service_ListDocServer) error + ListDoc(*Empty, Service_ListDocServer) error ListUsers(*ListUsersRequest, Service_ListUsersServer) error GPOListScript(*Empty, Service_GPOListScriptServer) error CertAutoEnrollScript(*Empty, Service_CertAutoEnrollScriptServer) error @@ -490,7 +490,7 @@ func (UnimplementedServiceServer) DumpPoliciesDefinitions(*DumpPolicyDefinitions func (UnimplementedServiceServer) GetDoc(*GetDocRequest, Service_GetDocServer) error { return status.Errorf(codes.Unimplemented, "method GetDoc not implemented") } -func (UnimplementedServiceServer) ListDoc(*ListDocRequest, Service_ListDocServer) error { +func (UnimplementedServiceServer) ListDoc(*Empty, Service_ListDocServer) error { return status.Errorf(codes.Unimplemented, "method ListDoc not implemented") } func (UnimplementedServiceServer) ListUsers(*ListUsersRequest, Service_ListUsersServer) error { @@ -684,7 +684,7 @@ func (x *serviceGetDocServer) Send(m *StringResponse) error { } func _Service_ListDoc_Handler(srv interface{}, stream grpc.ServerStream) error { - m := new(ListDocRequest) + m := new(Empty) if err := stream.RecvMsg(m); err != nil { return err } @@ -692,7 +692,7 @@ func _Service_ListDoc_Handler(srv interface{}, stream grpc.ServerStream) error { } type Service_ListDocServer interface { - Send(*StringResponse) error + Send(*ListDocReponse) error grpc.ServerStream } @@ -700,7 +700,7 @@ type serviceListDocServer struct { grpc.ServerStream } -func (x *serviceListDocServer) Send(m *StringResponse) error { +func (x *serviceListDocServer) Send(m *ListDocReponse) error { return x.ServerStream.SendMsg(m) } diff --git a/cmd/adsysd/client/client.go b/cmd/adsysd/client/client.go index 081e155da..035e3251b 100644 --- a/cmd/adsysd/client/client.go +++ b/cmd/adsysd/client/client.go @@ -45,6 +45,16 @@ func New() *App { Short: gotext.Get("AD integration client"), Long: gotext.Get(`Active Directory integration bridging toolset command line tool.`), PersistentPreRunE: func(cmd *cobra.Command, args []string) error { + // __complete does not parse flag. Only get interested into our config flag + if cmd.Name() == cobra.ShellCompRequestCmd { + for i, arg := range args { + if arg == "-c" || arg == "--config" { + if err := cmd.Flags().Set("config", args[i+1]); err != nil { + return err + } + } + } + } // command parsing has been successful. Returns runtime (or configuration) error now and so, don’t print usage. a.rootCmd.SilenceUsage = true err := config.Init("adsys", a.rootCmd, a.viper, func(refreshed bool) error { diff --git a/cmd/adsysd/client/doc.go b/cmd/adsysd/client/doc.go index caee5fb56..5597e6b1b 100644 --- a/cmd/adsysd/client/doc.go +++ b/cmd/adsysd/client/doc.go @@ -1,25 +1,18 @@ package client import ( - "errors" + "context" "fmt" - "os" - "path/filepath" - "strings" "github.com/charmbracelet/glamour" - "github.com/gomarkdown/markdown" - "github.com/gomarkdown/markdown/html" - "github.com/gomarkdown/markdown/parser" "github.com/leonelquinteros/gotext" "github.com/spf13/cobra" "github.com/ubuntu/adsys" - "github.com/ubuntu/adsys/doc" "github.com/ubuntu/adsys/internal/adsysservice" + log "github.com/ubuntu/adsys/internal/grpc/logstreamer" ) func (a *App) installDoc() { - var format, dest *string docCmd := &cobra.Command{ Use: "doc [CHAPTER]", Short: gotext.Get("Documentation"), @@ -33,53 +26,38 @@ func (a *App) installDoc() { return nil, cobra.ShellCompDirectiveNoFileComp } defer client.Close() - stream, err := client.ListDoc(a.ctx, &adsys.ListDocRequest{Raw: true}) + stream, err := client.ListDoc(a.ctx, &adsys.Empty{}) if err != nil { + log.Errorf(context.Background(), "could not connect to adsysd: %v", err) return nil, cobra.ShellCompDirectiveNoFileComp } - list, err := singleMsg(stream) + r, err := stream.Recv() if err != nil { + log.Errorf(context.Background(), "could not receive shell completion message: %v", err) return nil, cobra.ShellCompDirectiveNoFileComp } - - return strings.Split(list, "\n"), cobra.ShellCompDirectiveNoFileComp + return r.GetChapters(), cobra.ShellCompDirectiveNoFileComp }, RunE: func(cmd *cobra.Command, args []string) error { var chapter string if len(args) > 0 { chapter = args[0] } - return a.getDocumentation(chapter, *format, *dest) + return a.getDocumentation(chapter) }, } - format = docCmd.Flags().StringP("format", "f", "markdown", gotext.Get("Format type (markdown, raw or html).")) - dest = docCmd.Flags().StringP("dest", "d", "", gotext.Get("Write documentation file(s) to this directory.")) a.rootCmd.AddCommand(docCmd) } -func (a *App) getDocumentation(chapter, format, dest string) error { - if format != "markdown" && format != "raw" && format != "html" { - return fmt.Errorf("format can only be markdown, raw or html. Got %q", format) - } - +func (a *App) getDocumentation(chapter string) error { client, err := adsysservice.NewClient(a.config.Socket, a.getTimeout()) if err != nil { return err } defer client.Close() - var stream recver - var withHeader bool - if dest != "" { - stream, err = client.GetDoc(a.ctx, &adsys.GetDocRequest{Chapter: chapter}) - withHeader = true - } else if chapter == "" { - stream, err = client.ListDoc(a.ctx, &adsys.ListDocRequest{Raw: false}) - } else { - stream, err = client.GetDoc(a.ctx, &adsys.GetDocRequest{Chapter: chapter}) - withHeader = true - } + stream, err := client.GetDoc(a.ctx, &adsys.GetDocRequest{Chapter: chapter}) if err != nil { return err } @@ -89,56 +67,17 @@ func (a *App) getDocumentation(chapter, format, dest string) error { return err } - for _, out := range strings.Split(content, doc.SplitFilesToken) { - if len(out) == 0 { - continue - } - var filename string - if withHeader { - d := strings.SplitN(out, "\n", 2) - filename, out = d[0], d[1] - } - - var ext string - switch format { - case "markdown": - // Transform stdout content - if dest == "" { - r, err := glamour.NewTermRenderer(glamour.WithEnvironmentConfig()) - if err != nil { - return err - } - out, err = r.Render(out) - if err != nil { - return err - } - } - ext = ".md" - case "html": - extensions := parser.CommonExtensions | parser.AutoHeadingIDs - parser := parser.NewWithExtensions(extensions) - htmlFlags := html.CommonFlags | html.HrefTargetBlank | html.TOC | html.CompletePage - opts := html.RendererOptions{Flags: htmlFlags} - renderer := html.NewRenderer(opts) - out = string(markdown.ToHTML([]byte(out), parser, renderer)) - ext = ".html" - default: - } - - // Write directly on stdout - if dest == "" { - fmt.Print(out) - continue - } - - // Dump documentation in a directory - if err = os.MkdirAll(dest, 0750); err != nil { - return errors.New(gotext.Get("can't create %q", dest)) - } - if err := os.WriteFile(filepath.Join(dest, filename+ext), []byte(out), 0600); err != nil { - return errors.New(gotext.Get("can't write documentation chapter %q: %v", filename+ext, err)) - } + // Transform stdout content + r, err := glamour.NewTermRenderer(glamour.WithEnvironmentConfig()) + if err != nil { + return err } + out, err := r.Render(content) + if err != nil { + return err + } + + fmt.Print(out) return nil } diff --git a/cmd/adsysd/client/policy.go b/cmd/adsysd/client/policy.go index db8ef39e4..ba546274d 100644 --- a/cmd/adsysd/client/policy.go +++ b/cmd/adsysd/client/policy.go @@ -80,7 +80,7 @@ func (a *App) installPolicy() { policyCmd.AddCommand(debugCmd) gpoListCmd := &cobra.Command{ Use: "gpolist-script", - Short: gotext.Get("Write GPO list python embeeded script in current directory"), + Short: gotext.Get("Write GPO list python embedded script in current directory"), Args: cobra.NoArgs, ValidArgsFunction: cmdhandler.NoValidArgs, RunE: func(cmd *cobra.Command, args []string) error { return a.dumpGPOListScript() }, diff --git a/cmd/adsysd/daemon/daemon.go b/cmd/adsysd/daemon/daemon.go index 2e8588b94..9ba9f4d32 100644 --- a/cmd/adsysd/daemon/daemon.go +++ b/cmd/adsysd/daemon/daemon.go @@ -152,9 +152,9 @@ func New() *App { cmdhandler.InstallConfigFlag(&a.rootCmd, true) cmdhandler.InstallSocketFlag(&a.rootCmd, a.viper, consts.DefaultSocket) - a.rootCmd.PersistentFlags().StringP("cache-dir", "", consts.DefaultCacheDir, gotext.Get("directory where ADsys caches GPOs downloads and policies.")) + a.rootCmd.PersistentFlags().StringP("cache-dir", "", consts.DefaultCacheDir, gotext.Get("directory where ADSys caches GPOs downloads and policies.")) decorate.LogOnError(a.viper.BindPFlag("cache_dir", a.rootCmd.PersistentFlags().Lookup("cache-dir"))) - a.rootCmd.PersistentFlags().StringP("run-dir", "", consts.DefaultRunDir, gotext.Get("directory where ADsys stores transient information erased on reboot.")) + a.rootCmd.PersistentFlags().StringP("run-dir", "", consts.DefaultRunDir, gotext.Get("directory where ADSys stores transient information erased on reboot.")) decorate.LogOnError(a.viper.BindPFlag("run_dir", a.rootCmd.PersistentFlags().Lookup("run-dir"))) a.rootCmd.PersistentFlags().IntP("timeout", "t", consts.DefaultServiceTimeout, gotext.Get("time in seconds without activity before the service exists. 0 for no timeout.")) diff --git a/cmd/adsysd/integration_tests/adsysctl_doc_test.go b/cmd/adsysd/integration_tests/adsysctl_doc_test.go index fb0e3d2e3..220d103e3 100644 --- a/cmd/adsysd/integration_tests/adsysctl_doc_test.go +++ b/cmd/adsysd/integration_tests/adsysctl_doc_test.go @@ -1,53 +1,44 @@ package adsys_test import ( - "os" + "io/fs" "path/filepath" "strings" "testing" - "github.com/leonelquinteros/gotext" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/ubuntu/adsys/doc" ) func TestDocChapter(t *testing.T) { t.Setenv("GLAMOUR_STYLE", "notty") - fullName, strippedExt, baseName := getTestChapter(t, "02.") - tests := map[string]struct { - chapter string - format string - withDest bool - modifyCase bool + chapter string + systemAnswer string daemonNotStarted bool - wantErr bool + wantInDoc string + wantErr bool }{ - "Get documentation chapter": {chapter: baseName}, - "Get raw documentation": {chapter: baseName, format: "raw"}, - "Get html documentation": {chapter: baseName, format: "html"}, + "Get documentation chapter": {chapter: "how-to-guides/set-up-ad", wantInDoc: "# How to set up the Active Directory Server"}, + "Get documentation chapter with incorrect case": {chapter: "HoW-to-guIdes/set-Up-AD", wantInDoc: "# How to set up the Active Directory Server"}, - "Write all documentation": {withDest: true}, - "Write one documentation": {chapter: baseName, withDest: true}, - "Write documentation in raw format": {chapter: baseName, format: "raw", withDest: true}, - "Write documentation in html format": {chapter: baseName, format: "html", withDest: true}, + // Section cases + "Section using alias": {chapter: "how-to-guides", wantInDoc: "# How-to guides"}, + "Section using alias terminated by /": {chapter: "how-to-guides/", wantInDoc: "# How-to guides"}, + "Section using title instead of alias": {chapter: "explanation", wantInDoc: "Scripts execution"}, - // Tried to match filename - "Get documentation chapter with prefix": {chapter: strippedExt}, - "Get documentation chapter with full name": {chapter: fullName}, - "Get documentation chapter with non matching case": {chapter: baseName, modifyCase: true}, + // Main index cases + "Get main index with no parameter": {wantInDoc: "# ADSys Documentation"}, + "Get main index with index title doc name": {chapter: "adsys-documentation", wantInDoc: "# ADSys Documentation"}, - "Get documentation is always authorized": {systemAnswer: "polkit_no", chapter: baseName}, + "Get documentation is always authorized": {systemAnswer: "polkit_no", chapter: "how-to-guides/set-up-ad", wantInDoc: "# How to set up the Active Directory Server"}, // Error cases - "Error on daemon not responding": {daemonNotStarted: true, wantErr: true}, - "Error on nonexistent chapter": {chapter: "nonexistent-chapter", wantErr: true}, - "Error on exact name matching with wrong case": {chapter: fullName, modifyCase: true, wantErr: true}, - "Error on documentation in unknown format": {format: "unknown format", wantErr: true}, + "Error on daemon not responding": {daemonNotStarted: true, wantErr: true}, + "Error on nonexistent chapter": {chapter: "nonexistent-chapter", wantErr: true}, } for name, tc := range tests { tc := tc @@ -57,13 +48,6 @@ func TestDocChapter(t *testing.T) { } dbusAnswer(t, tc.systemAnswer) - if tc.modifyCase { - tc.chapter = strings.ToUpper(tc.chapter) - if strings.HasSuffix(tc.chapter, ".MD") { - tc.chapter = strings.TrimSuffix(tc.chapter, ".MD") + ".md" - } - } - conf := createConf(t) if !tc.daemonNotStarted { defer runDaemon(t, conf)() @@ -73,16 +57,7 @@ func TestDocChapter(t *testing.T) { if tc.chapter != "" { args = append(args, tc.chapter) } - if tc.format != "" { - args = append(args, "--format", tc.format) - } - var dest string - if tc.withDest { - dest = t.TempDir() - err := os.RemoveAll(dest) - require.NoError(t, err, "Setup: can’t delete destination directory") - args = append(args, "--dest", dest) - } + out, err := runClient(t, conf, args...) if tc.wantErr { require.Error(t, err, "client should exit with an error") @@ -92,69 +67,28 @@ func TestDocChapter(t *testing.T) { require.NoError(t, err, "client should exit with no error") // Printing on stdout - if !tc.withDest { - require.NotEmpty(t, out, "some documentation is printed") - // Images urls are translated to online version - assert.NotContains(t, out, "(images/", "No local images are referenced") - - switch tc.format { - case "markdown": - assert.True(t, strings.HasPrefix(out, "\n "), "markdown should be rendered") - assert.Contains(t, out, "###", "markdown should be printed") - case "html": - assert.Contains(t, out, "", "html should be printed") - case "raw": - assert.False(t, strings.HasPrefix(out, "\n "), "markdown should not be rendered") - } - return - } + require.NotEmpty(t, out, "some documentation is printed") + require.Contains(t, out, tc.wantInDoc, "Contains part of the expected doc content") - // Documentation written on disk - fs, err := os.ReadDir(dest) - require.NoError(t, err, "Destination directory exists") - if tc.chapter == "" { - require.True(t, len(fs) > 1, "Multiple files are created when requesting the whole documentation") - } - for _, f := range fs { - content, err := os.ReadFile(filepath.Join(dest, f.Name())) - require.NoError(t, err, "Can't read destination file") - - out = string(content) - var ext string - switch tc.format { - case "markdown": - ext = ".md" - assert.True(t, strings.HasPrefix(out, "\n "), "markdown should be rendered") - assert.Contains(t, out, "###", "markdown should be printed") - case "html": - ext = ".html" - assert.Contains(t, out, "", "html should be printed") - case "raw": - assert.False(t, strings.HasPrefix(out, "\n "), "markdown should not be rendered") - } - require.True(t, strings.HasSuffix(f.Name(), ext), "File %q has expected suffix: %q", f.Name(), ext) - } + // Note: (../images will be invalid when images are moved and this assertion will still be true + assert.NotContains(t, out, "(../images/", "Local images are referenced, and replaced with online version") }) } } -func TestDocList(t *testing.T) { - t.Setenv("GLAMOUR_STYLE", "notty") - +func TestDocCompletion(t *testing.T) { tests := map[string]struct { - raw bool systemAnswer string daemonNotStarted bool - wantErr bool + wantCompletionEmpty bool }{ - "List every documentation chapter": {}, - "Raw list of everu documentation chapter": {raw: true}, + "Completion lists main index, one section and one document": {}, - "List documentation is always authorized": {systemAnswer: "polkit_no"}, + "Completion on documentation is always authorized": {systemAnswer: "polkit_no"}, // Error cases - "Daemon not responding": {daemonNotStarted: true, wantErr: true}, + "Empty completion content on daemon not responding": {daemonNotStarted: true, wantCompletionEmpty: true}, } for name, tc := range tests { tc := tc @@ -169,59 +103,39 @@ func TestDocList(t *testing.T) { defer runDaemon(t, conf)() } - args := []string{"doc"} - if tc.raw { - args = append(args, "--format", "raw") - } + args := []string{"__complete", "doc", ""} out, err := runClient(t, conf, args...) - if tc.wantErr { - require.Error(t, err, "client should exit with an error") - return - } - require.NoError(t, err, "client should exit with no error") - require.NotEmpty(t, out, "some list is printed") - - // Ensure all chapters are listed - fs, err := doc.Dir.ReadDir(".") - require.NoError(t, err, "can’t list documentation directory") - for _, f := range fs { - // Assume we respect the -chaptername.md schema - n := strings.TrimSuffix(strings.SplitN(f.Name(), "-", 2)[1], ".md") - assert.Contains(t, out, n, "Chapter is listed") - } - if tc.raw { - assert.False(t, strings.HasPrefix(out, "\n "), "markdown should not be rendered") - } else { - assert.True(t, strings.HasPrefix(out, "\n "), "markdown should be rendered") + completions := strings.Split(out, "\n") + + if tc.wantCompletionEmpty { + require.Len(t, completions, 2, "Should list no completion apart from :4 and empty") + return } - }) - } -} -// Returns the names(s) of the chapter used for testing corresponding to chapterPrefix, -// so tests do not break if chapters are renamed. -func getTestChapter(t *testing.T, chapterPrefix string) (fullName string, strippedExt string, baseName string) { - t.Helper() + // Ensure that all interesting docs are listed here (and so. linked to their TOC) + var wantNumDocs int + docsDir := filepath.Join(rootProjectDir, "docs") + err = filepath.WalkDir(docsDir, func(path string, d fs.DirEntry, err error) error { + // Ignore directories, every reference doc under reuse and compiled content. + if d.IsDir() || strings.HasPrefix(path, filepath.Join(docsDir, "reuse")) || strings.HasPrefix(path, docsDir+"/.") { + return nil + } + if !strings.HasSuffix(d.Name(), ".md") { + return nil + } + wantNumDocs++ - fs, err := doc.Dir.ReadDir(".") - if err != nil { - t.Fatal(gotext.Get("could not list documentation directory: %v", err)) - } + return nil + }) + require.NoError(t, err, "Setup: could not list existing doc on tests for tests to compare") - // Sort all file names while they have their prefix - var name string - for _, f := range fs { - if !strings.HasPrefix(f.Name(), chapterPrefix) { - continue - } - name = f.Name() - } + // +2 as we have :4 for no file completion + empty string + assert.Len(t, completions, wantNumDocs+2, "Should list all available documentation md files from docs/") - if name == "" { - t.Fatal(gotext.Get("could not find chapter starting with %s", chapterPrefix)) + assert.Contains(t, completions, "how-to-guides", "contain a section index") + assert.Contains(t, completions, "how-to-guides/set-up-ad", "contain a section sub chapter with alias") + }) } - - return name, strings.TrimSuffix(name, ".md"), strings.TrimPrefix(strings.TrimSuffix(name, ".md"), chapterPrefix+"-") } diff --git a/cmd/generate_completion_documentation.go b/cmd/generate_completion_documentation.go index b63f565dd..d6d1b7911 100644 --- a/cmd/generate_completion_documentation.go +++ b/cmd/generate_completion_documentation.go @@ -60,12 +60,13 @@ func main() { if generators.InstallOnlyMode() { return } - updateFromCmd(commands, "README.md") case "update-doc-cli-ref": if generators.InstallOnlyMode() { return } - updateFromCmd(commands, filepath.Join("doc", "16.-Command-line-reference.md")) + for _, cmd := range commands { + updateDocReferenceFromCmd(cmd, filepath.Join("docs", "reference", fmt.Sprintf("%s-cli.md", strings.ToLower(cmd.Name())))) + } default: log.Fatalf(usage, os.Args[0]) } @@ -121,9 +122,9 @@ func genManPages(cmds []cobra.Command, dir string) { } } -// updateFromCmd creates a file containing the detail of the commands +// updateDocReferenceFromCmd creates a file containing the detail of the commands // the target filePath is relative to the root of the project -func updateFromCmd(cmds []cobra.Command, filePath string) { +func updateDocReferenceFromCmd(cmd cobra.Command, filePath string) { _, current, _, ok := runtime.Caller(1) if !ok { log.Fatal("Couldn't find current file name") @@ -131,58 +132,22 @@ func updateFromCmd(cmds []cobra.Command, filePath string) { targetFile := filepath.Join(filepath.Dir(current), "..", filePath) - in, err := os.Open(targetFile) - if err != nil { - log.Fatalf("Couldn't open source readme file: %v", err) - } - defer in.Close() - tmp, err := os.Create(targetFile + ".new") if err != nil { log.Fatalf("Couldn't create temporary readme file: %v", err) } defer tmp.Close() - src := bufio.NewScanner(in) - // Write header - for src.Scan() { - mustWriteLine(tmp, src.Text()) - if src.Text() == "## Usage" { - mustWriteLine(tmp, "") - break - } - } - if err := src.Err(); err != nil { - log.Fatalf("Error when scanning source readme file: %v", err) - } + mustWriteLine(tmp, fmt.Sprintf("# %s command line\n", cmd.Name())) // Write markdown - user, hidden := getCmdsAndHiddens(cmds) - mustWriteLine(tmp, "### User commands\n") + user, hidden := getUserAndHiddenCmds(cmd) + mustWriteLine(tmp, "## User commands\n") filterCommandMarkdown(user, tmp) - mustWriteLine(tmp, "### Hidden commands\n") + mustWriteLine(tmp, "## Hidden commands\n") mustWriteLine(tmp, "Those commands are hidden from help and should primarily be used by the system or for debugging.\n") filterCommandMarkdown(hidden, tmp) - // Write footer (skip previously generated content) - skip := true - for src.Scan() { - if strings.HasPrefix(src.Text(), "## ") { - skip = false - } - if skip { - continue - } - - mustWriteLine(tmp, src.Text()) - } - if err := src.Err(); err != nil { - log.Fatalf("Error when scanning source readme file: %v", err) - } - - if err := in.Close(); err != nil { - log.Fatalf("Couldn't close source Rreadme file: %v", err) - } if err := tmp.Close(); err != nil { log.Fatalf("Couldn't close temporary readme file: %v", err) } @@ -234,21 +199,12 @@ func genManTreeFromOpts(cmd *cobra.Command, opts doc.GenManTreeOptions) error { return doc.GenMan(cmd, &headerCopy, f) } -func getCmdsAndHiddens(cmds []cobra.Command) (user []cobra.Command, hidden []cobra.Command) { - for _, cmd := range cmds { - cmd := cmd - // Run ExecuteC to install completion and help commands - _, _ = cmd.ExecuteC() - user = append(user, cmd) - user = append(user, collectSubCmds(cmd, false /* selectHidden */, false /* parentWasHidden */)...) - } - - for _, cmd := range cmds { - cmd := cmd - // Run ExecuteC to install completion and help commands - _, _ = cmd.ExecuteC() - hidden = append(hidden, collectSubCmds(cmd, true /* selectHidden */, false /* parentWasHidden */)...) - } +func getUserAndHiddenCmds(cmd cobra.Command) (user []cobra.Command, hidden []cobra.Command) { + // Run ExecuteC to install completion and help commands + _, _ = cmd.ExecuteC() + user = append(user, cmd) + user = append(user, collectSubCmds(cmd, false /* selectHidden */, false /* parentWasHidden */)...) + hidden = append(hidden, collectSubCmds(cmd, true /* selectHidden */, false /* parentWasHidden */)...) return user, hidden } @@ -305,9 +261,9 @@ func filterCommandMarkdown(cmds []cobra.Command, w io.Writer) { continue } - // Add 2 levels of subindentation + // Add 1 level of subindentation if strings.HasPrefix(l, "##") { - l = "##" + l + l = "#" + l } // Special case # Linux an # macOS in shell completion: diff --git a/doc/01.-Welcome.md b/doc/01.-Welcome.md deleted file mode 100644 index 68f167eb1..000000000 --- a/doc/01.-Welcome.md +++ /dev/null @@ -1,32 +0,0 @@ -# ADSys: Active Directory Group Policy integration - -**ADSys** is the **Active Directory Group Policy client** for Ubuntu. It allows system administrators to manage and control Ubuntu Desktop clients from a central Microsoft Active Directory. -The project contains everything you need to integrate Ubuntu to your Active Directory, including **admx** and **adml** template files. - -The role of **ADSys** is solely the configuration of the host via Active Directory. Authentication of the users, initial security policy of the `Default Domain Policy` and creation of the home directory is still the responsibility of SSSD/Winbind and PAM. -Once an Ubuntu client is configured, Active Directory Group Policies are applied on boot for the machine and at login time for each user, then refreshed periodically. - -It is composed of 2 parts: a daemon and a client and a command line interface: - -* The daemon - `adsysd` - implements the Group Policy protocol. It relies on Kerberos, Samba and LDAP for authentication and policy retrieval. -* The command line interface - `adsysctl` - controls the daemon and its status. - -## Supported releases - -**ADSys** is supported on Ubuntu starting from **20.04.2 LTS**, and tested with Windows Server 2019. - -Only Active Directory on-prem is supported. Azure Active Directory (AAD) is not yet supported but on the roadmap (No ETA at the moment). - -## Contributions are welcome! - -ADSys licence is [GPL v3](https://github.com/ubuntu/adsys/blob/main/LICENSE). - -The source code is available on [GitHub upstream repository](https://github.com/ubuntu/adsys). For non trivial changes, please [open a bug](https://github.com/ubuntu/adsys/issues/new) describing your intentions first so that we can discuss the best strategy. - -If you ever find an issue, you can report it following our [project template](https://github.com/ubuntu/adsys/issues/new). - -## Recommended readings - -* `adsysd help` or `man adsysd`. -* `adsysctl help` or `man adsysctl`. -* This documentation is also [available online](https://github.com/ubuntu/adsys/wiki) diff --git a/doc/02.-Prerequisites.md b/doc/02.-Prerequisites.md deleted file mode 100644 index 3fc53ca5d..000000000 --- a/doc/02.-Prerequisites.md +++ /dev/null @@ -1,98 +0,0 @@ -# Prerequisites and installation - -In order to use Group Policies on an Ubuntu client, the first thing to do is, of course, to join the computer to an Active Directory domain. - -There are 2 ways to join an AD domain: - - 1. At installation time with the Ubuntu Desktop installer. - 1. After installation, by manually setting up the connection to AD. - -## Joining Active Directory domain - -### Joining at installation time - -Joining during installation is only supported by the Ubuntu Desktop graphical installer Ubiquity. So, start an installation of Ubuntu Desktop as you would usually do and proceed to the page **"Who are you?"**. Enter user and computer name information. - -![Who are you installer screen](images/Prerequisites/installer-whoareyou.png) - -> *Note about the host name:* -> -> *In order to set and resolve the host name properly, you must enter the **Fully Qualified Domain Name** (FQDN) of the machine in the field "Your computer's name". For example, `host01.example.com` instead of only the host name `host01`.* -> -> *After installation you can check if it is correct with the command `hostname` and `hostname -f` which must return the name of the machine (`host01`) and the full name of the machine with the domain (`host01.example.com`) respectively.* - -Check the box **"Use Active Directory"** and click **"Continue"** to proceed with next step **"Configure Active Directory"**. - -On this page you can enter the address of the Active Directory controller and credentials of the user allowed to add machines to the domain. - -![Configure Active Directory installer screen](images/Prerequisites/installer-configure_ad.png) - -You can verify that the server is reachable by pressing **"Test Connection"**. - -Once all the information has been entered and is valid, press **"Continue"** to proceed with the remaining usual steps of the installation. - -At the end of the installation you can reboot the machine and you are ready to log in as a user of the domain on first boot. - -If anything goes wrong with the join process during installation, you will be notified by a dialog box. You can still reboot the machine, log in as the administrator user of the machine (ie the user you entered in the page **"Who are you?"**) and troubleshoot the issue. The [Ubuntu Server Guide](https://ubuntu.com/server/docs/service-sssd) provides instructions to perform such troubleshooting. - -### Joining manually using SSSD - -The purpose of this document is to describe how to operate ADSys. So we won’t do an in depth description of the operations to manually configure a connection to Active Directory from an Ubuntu Client. - -Authentication of Ubuntu against the Active Directory server requires to configure SSSD and Kerberos. SSSD will then retrieve the credentials and the initial security policy of the `Default Domain Policy`. - -All these operations are perfectly described in the [Ubuntu Server Guide “Service - SSSD”](https://ubuntu.com/server/docs/service-sssd) and the White Paper [How to integrate Ubuntu Desktop with Active Directory](https://ubuntu.com/engage/microsoft-active-directory). - -### Joining manually using Winbind - -In addition to SSSD, ADSys supports using Winbind as a backend. The easiest way to join a domain using Winbind is to use the `realmd` utility, as described in the [Samba - Active Directory](https://ubuntu.com/server/docs/samba-active-directory) guide. - -ADSys uses SSSD as a default backend, so Winbind has to be opted into explicitly via the following config option in `adsys.yaml`: - -```yaml -ad_backend: winbind -``` - -In addition, Winbind requires additional dependencies to be installed. On Ubuntu-based systems they can be installed by executing the following command, prior to ADSys: - -```sh -sudo apt update -sudo apt install winbind krb5-user -``` - -## Installing ADSys - -**ADSys** is not currently installed by default on Ubuntu desktop. This must be done manually by the local administrator of the machine. - -To do so, log in on first boot, update the repositories and install **ADSys**. On Ubuntu-based systems this can be accomplished with the following commands: - -```sh -sudo apt update -sudo apt install adsys -``` - -Reboot then to allow the machine to do its policy refresh. - -## Logging in as a user of the domain - -To log in as a user of the domain, press the link **"Not listed?"** in the greeter. Then enter the username followed by the password. - -### SSSD - -By default, there is no default domain configured in SSSD. You have to enter the full user name with one of the forms: `USER@DOMAIN.COM`, `USER@DOMAIN` or `DOMAIN/USER`. - -On the first log in the user's home directory is created. - -All of this (default domain, default path for home directories, default shell, etc.) is configurable in `/etc/sssd/sssd.conf`. - -### Winbind - -If Winbind is used as a backend, the account can be specified in one of the following forms: `USER@DOMAIN.COM`, `USER@DOMAIN` or `DOMAIN\\USER`. - -For the home directory to be created automatically on login, the `pam_mkhomedir` module can be enabled: - -```sh -sudo pam-auth-update --enable mkhomedir -``` - -Options such as the home directory path template, shell and others can be tweaked in `/etc/samba/smb.conf` and are documented in the [`smb.conf(5)`](https://www.samba.org/samba/docs/current/man-html/smb.conf.5.html) manpage. diff --git a/doc/16.-Command-line-reference.md b/doc/16.-Command-line-reference.md deleted file mode 100644 index 0d2fb640d..000000000 --- a/doc/16.-Command-line-reference.md +++ /dev/null @@ -1,1388 +0,0 @@ -# Command line reference - -## Usage - -### User commands - -#### adsysctl - -AD integration client - -##### Synopsis - -Active Directory integration bridging toolset command line tool. - -``` -adsysctl COMMAND [flags] -``` - -##### Options - -``` - -c, --config string use a specific configuration file - -h, --help help for adsysctl - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl applied - -Print last applied GPOs for current or given user/machine - -##### Synopsis - -Alias of "policy applied" - -``` -adsysctl applied [USER_NAME] [flags] -``` - -##### Options - -``` - -a, --all show overridden rules in each GPOs. - --details show applied rules in addition to GPOs. - -h, --help help for applied - -m, --machine show applied rules to the machine. - --no-color don't display colorized version. -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl completion - -Generate the autocompletion script for the specified shell - -##### Synopsis - -Generate the autocompletion script for adsysctl for the specified shell. -See each sub-command's help for details on how to use the generated script. - - -##### Options - -``` - -h, --help help for completion -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl completion bash - -Generate the autocompletion script for bash - -##### Synopsis - -Generate the autocompletion script for the bash shell. - -This script depends on the 'bash-completion' package. -If it is not installed already, you can install it via your OS's package manager. - -To load completions in your current shell session: - - source <(adsysctl completion bash) - -To load completions for every new session, execute once: - -###### Linux: - - adsysctl completion bash > /etc/bash_completion.d/adsysctl - -###### macOS: - - adsysctl completion bash > $(brew --prefix)/etc/bash_completion.d/adsysctl - -You will need to start a new shell for this setup to take effect. - - -``` -adsysctl completion bash -``` - -##### Options - -``` - -h, --help help for bash - --no-descriptions disable completion descriptions -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl completion fish - -Generate the autocompletion script for fish - -##### Synopsis - -Generate the autocompletion script for the fish shell. - -To load completions in your current shell session: - - adsysctl completion fish | source - -To load completions for every new session, execute once: - - adsysctl completion fish > ~/.config/fish/completions/adsysctl.fish - -You will need to start a new shell for this setup to take effect. - - -``` -adsysctl completion fish [flags] -``` - -##### Options - -``` - -h, --help help for fish - --no-descriptions disable completion descriptions -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl completion powershell - -Generate the autocompletion script for powershell - -##### Synopsis - -Generate the autocompletion script for powershell. - -To load completions in your current shell session: - - adsysctl completion powershell | Out-String | Invoke-Expression - -To load completions for every new session, add the output of the above command -to your powershell profile. - - -``` -adsysctl completion powershell [flags] -``` - -##### Options - -``` - -h, --help help for powershell - --no-descriptions disable completion descriptions -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl completion zsh - -Generate the autocompletion script for zsh - -##### Synopsis - -Generate the autocompletion script for the zsh shell. - -If shell completion is not already enabled in your environment you will need -to enable it. You can execute the following once: - - echo "autoload -U compinit; compinit" >> ~/.zshrc - -To load completions in your current shell session: - - source <(adsysctl completion zsh) - -To load completions for every new session, execute once: - -###### Linux: - - adsysctl completion zsh > "${fpath[1]}/_adsysctl" - -###### macOS: - - adsysctl completion zsh > $(brew --prefix)/share/zsh/site-functions/_adsysctl - -You will need to start a new shell for this setup to take effect. - - -``` -adsysctl completion zsh [flags] -``` - -##### Options - -``` - -h, --help help for zsh - --no-descriptions disable completion descriptions -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl doc - -Documentation - -``` -adsysctl doc [CHAPTER] [flags] -``` - -##### Options - -``` - -d, --dest string Write documentation file(s) to this directory. - -f, --format string Format type (markdown, raw or html). (default "markdown") - -h, --help help for doc -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl policy - -Policy management - -``` -adsysctl policy COMMAND [flags] -``` - -##### Options - -``` - -h, --help help for policy -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl policy admx - -Dump windows policy definitions - -``` -adsysctl policy admx lts-only|all [flags] -``` - -##### Options - -``` - --distro string distro for which to retrieve policy definition. (default "Ubuntu") - -h, --help help for admx -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl policy applied - -Print last applied GPOs for current or given user/machine - -``` -adsysctl policy applied [USER_NAME] [flags] -``` - -##### Options - -``` - -a, --all show overridden rules in each GPOs. - --details show applied rules in addition to GPOs. - -h, --help help for applied - -m, --machine show applied rules to the machine. - --no-color don't display colorized version. -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl policy purge - -Purges policies for the current user or a specified one - -``` -adsysctl policy purge [USER_NAME] [flags] -``` - -##### Options - -``` - -a, --all all purges the policy of the computer and all the logged in users. -m or USER_NAME cannot be used with this option. - -h, --help help for purge - -m, --machine machine purges the policy of the computer. -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl policy update - -Updates/Create a policy for current user or given user with its kerberos ticket - -``` -adsysctl policy update [USER_NAME KERBEROS_TICKET_PATH] [flags] -``` - -##### Options - -``` - -a, --all all updates the policy of the computer and all the logged in users. -m or USER_NAME/TICKET cannot be used with this option. - -h, --help help for update - -m, --machine machine updates the policy of the computer. -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl service - -Service management - -``` -adsysctl service COMMAND [flags] -``` - -##### Options - -``` - -h, --help help for service -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl service cat - -Print service logs - -``` -adsysctl service cat [flags] -``` - -##### Options - -``` - -h, --help help for cat -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl service status - -Print service status - -``` -adsysctl service status [flags] -``` - -##### Options - -``` - -h, --help help for status -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl service stop - -Requests to stop the service once all connections are done - -``` -adsysctl service stop [flags] -``` - -##### Options - -``` - -f, --force force will shut it down immediately and drop existing connections. - -h, --help help for stop -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl update - -Updates/Create a policy for current user or given user with its kerberos ticket - -##### Synopsis - -Alias of "policy update" - -``` -adsysctl update [USER_NAME KERBEROS_TICKET_PATH] [flags] -``` - -##### Options - -``` - -a, --all all updates the policy of the computer and all the logged in users. -m or USER_NAME/TICKET cannot be used with this option. - -h, --help help for update - -m, --machine machine updates the policy of the computer. -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl version - -Returns version of client and service - -``` -adsysctl version [flags] -``` - -##### Options - -``` - -h, --help help for version -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysd - -AD integration daemon - -##### Synopsis - -Active Directory integration bridging toolset daemon. - -``` -adsysd COMMAND [flags] -``` - -##### Options - -``` - --ad-backend string Active Directory authentication backend (default "sssd") - --cache-dir string directory where ADsys caches GPOs downloads and policies. (default "/var/cache/adsys") - -c, --config string use a specific configuration file - -h, --help help for adsysd - --run-dir string directory where ADsys stores transient information erased on reboot. (default "/run/adsys") - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - --sssd.cache-dir string SSSd cache directory (default "/var/lib/sss/db") - --sssd.config string SSSd config file path (default "/etc/sssd/sssd.conf") - -t, --timeout int time in seconds without activity before the service exists. 0 for no timeout. (default 120) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysd completion - -Generate the autocompletion script for the specified shell - -##### Synopsis - -Generate the autocompletion script for adsysd for the specified shell. -See each sub-command's help for details on how to use the generated script. - - -##### Options - -``` - -h, --help help for completion -``` - -##### Options inherited from parent commands - -``` - --ad-backend string Active Directory authentication backend (default "sssd") - --cache-dir string directory where ADsys caches GPOs downloads and policies. (default "/var/cache/adsys") - -c, --config string use a specific configuration file - --run-dir string directory where ADsys stores transient information erased on reboot. (default "/run/adsys") - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - --sssd.cache-dir string SSSd cache directory (default "/var/lib/sss/db") - --sssd.config string SSSd config file path (default "/etc/sssd/sssd.conf") - -t, --timeout int time in seconds without activity before the service exists. 0 for no timeout. (default 120) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysd completion bash - -Generate the autocompletion script for bash - -##### Synopsis - -Generate the autocompletion script for the bash shell. - -This script depends on the 'bash-completion' package. -If it is not installed already, you can install it via your OS's package manager. - -To load completions in your current shell session: - - source <(adsysd completion bash) - -To load completions for every new session, execute once: - -###### Linux: - - adsysd completion bash > /etc/bash_completion.d/adsysd - -###### macOS: - - adsysd completion bash > $(brew --prefix)/etc/bash_completion.d/adsysd - -You will need to start a new shell for this setup to take effect. - - -``` -adsysd completion bash -``` - -##### Options - -``` - -h, --help help for bash - --no-descriptions disable completion descriptions -``` - -##### Options inherited from parent commands - -``` - --ad-backend string Active Directory authentication backend (default "sssd") - --cache-dir string directory where ADsys caches GPOs downloads and policies. (default "/var/cache/adsys") - -c, --config string use a specific configuration file - --run-dir string directory where ADsys stores transient information erased on reboot. (default "/run/adsys") - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - --sssd.cache-dir string SSSd cache directory (default "/var/lib/sss/db") - --sssd.config string SSSd config file path (default "/etc/sssd/sssd.conf") - -t, --timeout int time in seconds without activity before the service exists. 0 for no timeout. (default 120) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysd completion fish - -Generate the autocompletion script for fish - -##### Synopsis - -Generate the autocompletion script for the fish shell. - -To load completions in your current shell session: - - adsysd completion fish | source - -To load completions for every new session, execute once: - - adsysd completion fish > ~/.config/fish/completions/adsysd.fish - -You will need to start a new shell for this setup to take effect. - - -``` -adsysd completion fish [flags] -``` - -##### Options - -``` - -h, --help help for fish - --no-descriptions disable completion descriptions -``` - -##### Options inherited from parent commands - -``` - --ad-backend string Active Directory authentication backend (default "sssd") - --cache-dir string directory where ADsys caches GPOs downloads and policies. (default "/var/cache/adsys") - -c, --config string use a specific configuration file - --run-dir string directory where ADsys stores transient information erased on reboot. (default "/run/adsys") - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - --sssd.cache-dir string SSSd cache directory (default "/var/lib/sss/db") - --sssd.config string SSSd config file path (default "/etc/sssd/sssd.conf") - -t, --timeout int time in seconds without activity before the service exists. 0 for no timeout. (default 120) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysd completion powershell - -Generate the autocompletion script for powershell - -##### Synopsis - -Generate the autocompletion script for powershell. - -To load completions in your current shell session: - - adsysd completion powershell | Out-String | Invoke-Expression - -To load completions for every new session, add the output of the above command -to your powershell profile. - - -``` -adsysd completion powershell [flags] -``` - -##### Options - -``` - -h, --help help for powershell - --no-descriptions disable completion descriptions -``` - -##### Options inherited from parent commands - -``` - --ad-backend string Active Directory authentication backend (default "sssd") - --cache-dir string directory where ADsys caches GPOs downloads and policies. (default "/var/cache/adsys") - -c, --config string use a specific configuration file - --run-dir string directory where ADsys stores transient information erased on reboot. (default "/run/adsys") - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - --sssd.cache-dir string SSSd cache directory (default "/var/lib/sss/db") - --sssd.config string SSSd config file path (default "/etc/sssd/sssd.conf") - -t, --timeout int time in seconds without activity before the service exists. 0 for no timeout. (default 120) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysd completion zsh - -Generate the autocompletion script for zsh - -##### Synopsis - -Generate the autocompletion script for the zsh shell. - -If shell completion is not already enabled in your environment you will need -to enable it. You can execute the following once: - - echo "autoload -U compinit; compinit" >> ~/.zshrc - -To load completions in your current shell session: - - source <(adsysd completion zsh) - -To load completions for every new session, execute once: - -###### Linux: - - adsysd completion zsh > "${fpath[1]}/_adsysd" - -###### macOS: - - adsysd completion zsh > $(brew --prefix)/share/zsh/site-functions/_adsysd - -You will need to start a new shell for this setup to take effect. - - -``` -adsysd completion zsh [flags] -``` - -##### Options - -``` - -h, --help help for zsh - --no-descriptions disable completion descriptions -``` - -##### Options inherited from parent commands - -``` - --ad-backend string Active Directory authentication backend (default "sssd") - --cache-dir string directory where ADsys caches GPOs downloads and policies. (default "/var/cache/adsys") - -c, --config string use a specific configuration file - --run-dir string directory where ADsys stores transient information erased on reboot. (default "/run/adsys") - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - --sssd.cache-dir string SSSd cache directory (default "/var/lib/sss/db") - --sssd.config string SSSd config file path (default "/etc/sssd/sssd.conf") - -t, --timeout int time in seconds without activity before the service exists. 0 for no timeout. (default 120) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysd version - -Returns version of service and exits - -``` -adsysd version [flags] -``` - -##### Options - -``` - -h, --help help for version -``` - -##### Options inherited from parent commands - -``` - --ad-backend string Active Directory authentication backend (default "sssd") - --cache-dir string directory where ADsys caches GPOs downloads and policies. (default "/var/cache/adsys") - -c, --config string use a specific configuration file - --run-dir string directory where ADsys stores transient information erased on reboot. (default "/run/adsys") - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - --sssd.cache-dir string SSSd cache directory (default "/var/lib/sss/db") - --sssd.config string SSSd config file path (default "/etc/sssd/sssd.conf") - -t, --timeout int time in seconds without activity before the service exists. 0 for no timeout. (default 120) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adwatchd - -AD watch daemon - -##### Synopsis - -Watch directories for changes and bump the relevant GPT.ini versions. - -``` -adwatchd [COMMAND] [flags] -``` - -##### Options - -``` - -c, --config string use a specific configuration file - -h, --help help for adwatchd - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adwatchd completion - -Generate the autocompletion script for the specified shell - -##### Synopsis - -Generate the autocompletion script for adwatchd for the specified shell. -See each sub-command's help for details on how to use the generated script. - - -##### Options - -``` - -h, --help help for completion -``` - -##### Options inherited from parent commands - -``` - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adwatchd completion bash - -Generate the autocompletion script for bash - -##### Synopsis - -Generate the autocompletion script for the bash shell. - -This script depends on the 'bash-completion' package. -If it is not installed already, you can install it via your OS's package manager. - -To load completions in your current shell session: - - source <(adwatchd completion bash) - -To load completions for every new session, execute once: - -###### Linux: - - adwatchd completion bash > /etc/bash_completion.d/adwatchd - -###### macOS: - - adwatchd completion bash > $(brew --prefix)/etc/bash_completion.d/adwatchd - -You will need to start a new shell for this setup to take effect. - - -``` -adwatchd completion bash -``` - -##### Options - -``` - -h, --help help for bash - --no-descriptions disable completion descriptions -``` - -##### Options inherited from parent commands - -``` - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adwatchd completion fish - -Generate the autocompletion script for fish - -##### Synopsis - -Generate the autocompletion script for the fish shell. - -To load completions in your current shell session: - - adwatchd completion fish | source - -To load completions for every new session, execute once: - - adwatchd completion fish > ~/.config/fish/completions/adwatchd.fish - -You will need to start a new shell for this setup to take effect. - - -``` -adwatchd completion fish [flags] -``` - -##### Options - -``` - -h, --help help for fish - --no-descriptions disable completion descriptions -``` - -##### Options inherited from parent commands - -``` - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adwatchd completion powershell - -Generate the autocompletion script for powershell - -##### Synopsis - -Generate the autocompletion script for powershell. - -To load completions in your current shell session: - - adwatchd completion powershell | Out-String | Invoke-Expression - -To load completions for every new session, add the output of the above command -to your powershell profile. - - -``` -adwatchd completion powershell [flags] -``` - -##### Options - -``` - -h, --help help for powershell - --no-descriptions disable completion descriptions -``` - -##### Options inherited from parent commands - -``` - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adwatchd completion zsh - -Generate the autocompletion script for zsh - -##### Synopsis - -Generate the autocompletion script for the zsh shell. - -If shell completion is not already enabled in your environment you will need -to enable it. You can execute the following once: - - echo "autoload -U compinit; compinit" >> ~/.zshrc - -To load completions in your current shell session: - - source <(adwatchd completion zsh) - -To load completions for every new session, execute once: - -###### Linux: - - adwatchd completion zsh > "${fpath[1]}/_adwatchd" - -###### macOS: - - adwatchd completion zsh > $(brew --prefix)/share/zsh/site-functions/_adwatchd - -You will need to start a new shell for this setup to take effect. - - -``` -adwatchd completion zsh [flags] -``` - -##### Options - -``` - -h, --help help for zsh - --no-descriptions disable completion descriptions -``` - -##### Options inherited from parent commands - -``` - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adwatchd run - -Starts the directory watch loop - -##### Synopsis - -Can run as a service through the service manager or interactively as a standalone application. - -The program will monitor the configured directories for changes and bump the appropriate GPT.ini versions anytime a change is detected. -If a GPT.ini file does not exist for a directory, a warning will be issued and the file will be created. If the GPT.ini file is incompatible or malformed, the program will report an error. - - -``` -adwatchd run [flags] -``` - -##### Options - -``` - -c, --config string use a specific configuration file - -d, --dirs directory a directory to check for changes (can be specified multiple times) - -f, --force force the program to run even if another instance is already running - -h, --help help for run -``` - -##### Options inherited from parent commands - -``` - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adwatchd service - -Manages the adwatchd service - -##### Synopsis - -The service command allows the user to interact with the adwatchd service. It can manage and query the service status, and also install and uninstall the service. - -``` -adwatchd service COMMAND [flags] -``` - -##### Options - -``` - -h, --help help for service -``` - -##### Options inherited from parent commands - -``` - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adwatchd service install - -Installs the service - -##### Synopsis - -Installs the adwatchd service. - -The service will be installed as a Windows service. - - -``` -adwatchd service install [flags] -``` - -##### Options - -``` - -c, --config string use a specific configuration file - -h, --help help for install -``` - -##### Options inherited from parent commands - -``` - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adwatchd service restart - -Restarts the service - -##### Synopsis - -Restarts the adwatchd service. - -``` -adwatchd service restart [flags] -``` - -##### Options - -``` - -h, --help help for restart -``` - -##### Options inherited from parent commands - -``` - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adwatchd service start - -Starts the service - -##### Synopsis - -Starts the adwatchd service. - -``` -adwatchd service start [flags] -``` - -##### Options - -``` - -h, --help help for start -``` - -##### Options inherited from parent commands - -``` - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adwatchd service status - -Returns service status - -##### Synopsis - -Returns the status of the adwatchd service. - -``` -adwatchd service status [flags] -``` - -##### Options - -``` - -h, --help help for status -``` - -##### Options inherited from parent commands - -``` - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adwatchd service stop - -Stops the service - -##### Synopsis - -Stops the adwatchd service. - -``` -adwatchd service stop [flags] -``` - -##### Options - -``` - -h, --help help for stop -``` - -##### Options inherited from parent commands - -``` - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adwatchd service uninstall - -Uninstalls the service - -##### Synopsis - -Uninstalls the adwatchd service. - -``` -adwatchd service uninstall [flags] -``` - -##### Options - -``` - -h, --help help for uninstall -``` - -##### Options inherited from parent commands - -``` - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adwatchd version - -Returns version of service and exits - -``` -adwatchd version [flags] -``` - -##### Options - -``` - -h, --help help for version -``` - -##### Options inherited from parent commands - -``` - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -### Hidden commands - -Those commands are hidden from help and should primarily be used by the system or for debugging. - -#### adsysctl policy debug - -Debug various policy infos - -``` -adsysctl policy debug [flags] -``` - -##### Options - -``` - -h, --help help for debug -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl policy debug cert-autoenroll-script - -Write certificate autoenrollment python embedded script in current directory - -``` -adsysctl policy debug cert-autoenroll-script [flags] -``` - -##### Options - -``` - -h, --help help for cert-autoenroll-script -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysctl policy debug gpolist-script - -Write GPO list python embeeded script in current directory - -``` -adsysctl policy debug gpolist-script [flags] -``` - -##### Options - -``` - -h, --help help for gpolist-script -``` - -##### Options inherited from parent commands - -``` - -c, --config string use a specific configuration file - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysd mount - -Mount the locations listed in the specified file for the current user - -``` -adsysd mount MOUNTS_FILE [flags] -``` - -##### Options - -``` - -h, --help help for mount -``` - -##### Options inherited from parent commands - -``` - --ad-backend string Active Directory authentication backend (default "sssd") - --cache-dir string directory where ADsys caches GPOs downloads and policies. (default "/var/cache/adsys") - -c, --config string use a specific configuration file - --run-dir string directory where ADsys stores transient information erased on reboot. (default "/run/adsys") - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - --sssd.cache-dir string SSSd cache directory (default "/var/lib/sss/db") - --sssd.config string SSSd config file path (default "/etc/sssd/sssd.conf") - -t, --timeout int time in seconds without activity before the service exists. 0 for no timeout. (default 120) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -#### adsysd runscripts - -Runs scripts in the given subdirectory - -``` -adsysd runscripts ORDER_FILE [flags] -``` - -##### Options - -``` - --allow-order-missing allow ORDER_FILE to be missing once the scripts are ready. - -h, --help help for runscripts -``` - -##### Options inherited from parent commands - -``` - --ad-backend string Active Directory authentication backend (default "sssd") - --cache-dir string directory where ADsys caches GPOs downloads and policies. (default "/var/cache/adsys") - -c, --config string use a specific configuration file - --run-dir string directory where ADsys stores transient information erased on reboot. (default "/run/adsys") - -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") - --sssd.cache-dir string SSSd cache directory (default "/var/lib/sss/db") - --sssd.config string SSSd config file path (default "/etc/sssd/sssd.conf") - -t, --timeout int time in seconds without activity before the service exists. 0 for no timeout. (default 120) - -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output -``` - -## More information - -These commands support shell completion and have a corresponding man page. diff --git a/doc/Home.md b/doc/Home.md deleted file mode 100644 index ac6781f36..000000000 --- a/doc/Home.md +++ /dev/null @@ -1,3 +0,0 @@ -Welcome to ADSys documentation! - -You can check the various documentation sections for your desired topic. They are ordered if you want to read the whole documentation for ease of use. \ No newline at end of file diff --git a/doc/_Footer.md b/doc/_Footer.md deleted file mode 100644 index db5910850..000000000 --- a/doc/_Footer.md +++ /dev/null @@ -1,2 +0,0 @@ -This documentation is also available on your local system with `adsysctl doc` command. - diff --git a/doc/doc.go b/doc/doc.go deleted file mode 100644 index 1f20437ac..000000000 --- a/doc/doc.go +++ /dev/null @@ -1,25 +0,0 @@ -// Package doc embeds structured adsys documentation. -package doc - -import ( - "embed" - "fmt" - "path/filepath" - "reflect" -) - -// Dir is the embedded directory containing documentation -// Only embed structured documentation. -// -//go:embed *-*.md -var Dir embed.FS - -// SplitFilesToken is the prefix between multiple documentation pages. -const SplitFilesToken = "----==----" - -type foo struct{} - -// GetPackageURL returns a distant link to a raw binary content related to this directory. -func GetPackageURL() string { - return fmt.Sprintf("https://%s/raw/main/doc", filepath.Dir(reflect.TypeOf(foo{}).PkgPath())) -} diff --git a/doc/images/Using-GPO/gpo_setting_enabled_with_override.png b/doc/images/Using-GPO/gpo_setting_enabled_with_override.png deleted file mode 100644 index 804c9ffab..000000000 Binary files a/doc/images/Using-GPO/gpo_setting_enabled_with_override.png and /dev/null differ diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 000000000..c8f8ee69f --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,8 @@ +/*env*/ +.sphinx/venv +.sphinx/warnings.txt +.sphinx/.wordlist.dic +_build +.DS_Store +__pycache__ +.idea/ diff --git a/docs/.readthedocs.yaml b/docs/.readthedocs.yaml new file mode 100644 index 000000000..45fe3a881 --- /dev/null +++ b/docs/.readthedocs.yaml @@ -0,0 +1,27 @@ +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the version of Python and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.11" + +# Build documentation in the docs/ directory with Sphinx +sphinx: + builder: dirhtml + configuration: docs/conf.py + fail_on_warning: true + +# If using Sphinx, optionally build your docs in additional formats such as PDF +formats: + - pdf + +# Optionally declare the Python requirements required to build your docs +python: + install: + - requirements: docs/.sphinx/requirements.txt diff --git a/docs/.sphinx/_static/custom.css b/docs/.sphinx/_static/custom.css new file mode 100644 index 000000000..cad94b74c --- /dev/null +++ b/docs/.sphinx/_static/custom.css @@ -0,0 +1,189 @@ +/** Fix the font weight (300 for normal, 400 for slightly bold) **/ + +div.page, h1, h2, h3, h4, h5, h6, .sidebar-tree .current-page>.reference, button, input, optgroup, select, textarea, th.head { + font-weight: 300 +} + +.toc-tree li.scroll-current>.reference, dl.glossary dt, dl.simple dt, dl:not([class]) dt { + font-weight: 400; +} + +/** Table styling **/ + +th.head { + text-transform: uppercase; + font-size: var(--font-size--small); +} + +table.docutils { + border: 0; + box-shadow: none; + width:100%; +} + +table.docutils td, table.docutils th, table.docutils td:last-child, table.docutils th:last-child, table.docutils td:first-child, table.docutils th:first-child { + border-right: none; + border-left: none; +} + +/* Allow to centre text horizontally in table data cells */ +table.align-center { + text-align: center !important; +} + +/** No rounded corners **/ + +.admonition, code.literal, .sphinx-tabs-tab, .sphinx-tabs-panel, .highlight { + border-radius: 0; +} + +/** Admonition styling **/ + +.admonition { + border-top: 1px solid #d9d9d9; + border-right: 1px solid #d9d9d9; + border-bottom: 1px solid #d9d9d9; +} + +/** Color for the "copy link" symbol next to headings **/ + +a.headerlink { + color: var(--color-brand-primary); +} + +/** Line to the left of the current navigation entry **/ + +.sidebar-tree li.current-page { + border-left: 2px solid var(--color-brand-primary); +} + +/** Some tweaks for issue #16 **/ + +[role="tablist"] { + border-bottom: 1px solid var(--color-sidebar-item-background--hover); +} + +.sphinx-tabs-tab[aria-selected="true"] { + border: 0; + border-bottom: 2px solid var(--color-brand-primary); + background-color: var(--color-sidebar-item-background--current); + font-weight:300; +} + +.sphinx-tabs-tab{ + color: var(--color-brand-primary); + font-weight:300; +} + +.sphinx-tabs-panel { + border: 0; + border-bottom: 1px solid var(--color-sidebar-item-background--hover); + background: var(--color-background-primary); +} + +button.sphinx-tabs-tab:hover { + background-color: var(--color-sidebar-item-background--hover); +} + +/** Custom classes to fix scrolling in tables by decreasing the + font size or breaking certain columns. + Specify the classes in the Markdown file with, for example: + ```{rst-class} break-col-4 min-width-4-8 + ``` +**/ + +table.dec-font-size { + font-size: smaller; +} +table.break-col-1 td.text-left:first-child { + word-break: break-word; +} +table.break-col-4 td.text-left:nth-child(4) { + word-break: break-word; +} +table.min-width-1-15 td.text-left:first-child { + min-width: 15em; +} +table.min-width-4-8 td.text-left:nth-child(4) { + min-width: 8em; +} + +/** Underline for abbreviations **/ + +abbr[title] { + text-decoration: underline solid #cdcdcd; +} + +/** Use the same style for right-details as for left-details **/ +.bottom-of-page .right-details { + font-size: var(--font-size--small); + display: block; +} + +/** Version switcher */ +button.version_select { + color: var(--color-foreground-primary); + background-color: var(--color-toc-background); + padding: 5px 10px; + border: none; +} + +.version_select:hover, .version_select:focus { + background-color: var(--color-sidebar-item-background--hover); +} + +.version_dropdown { + position: relative; + display: inline-block; + text-align: right; + font-size: var(--sidebar-item-font-size); +} + +.available_versions { + display: none; + position: absolute; + right: 0px; + background-color: var(--color-toc-background); + box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); + z-index: 11; +} + +.available_versions a { + color: var(--color-foreground-primary); + padding: 12px 16px; + text-decoration: none; + display: block; +} + +.available_versions a:hover {background-color: var(--color-sidebar-item-background--current)} + +.show {display:block;} + +/** Fix for nested numbered list - the nested list is lettered **/ +ol.arabic ol.arabic { + list-style: lower-alpha; +} + +/** Make expandable sections look like links **/ +details summary { + color: var(--color-link); +} + +/** Fix the styling of the version box for readthedocs **/ + +#furo-readthedocs-versions .rst-versions, #furo-readthedocs-versions .rst-current-version, #furo-readthedocs-versions:focus-within .rst-current-version, #furo-readthedocs-versions:hover .rst-current-version { + background: var(--color-sidebar-item-background--hover); +} + +.rst-versions .rst-other-versions dd a { + color: var(--color-link); +} + +#furo-readthedocs-versions:focus-within .rst-current-version .fa-book, #furo-readthedocs-versions:hover .rst-current-version .fa-book, .rst-versions .rst-other-versions { + color: var(--color-sidebar-link-text); +} + +.rst-versions .rst-current-version { + color: var(--color-version-popup); + font-weight: bolder; +} diff --git a/docs/.sphinx/_static/favicon.png b/docs/.sphinx/_static/favicon.png new file mode 100644 index 000000000..c7109908f Binary files /dev/null and b/docs/.sphinx/_static/favicon.png differ diff --git a/docs/.sphinx/_static/github_issue_links.css b/docs/.sphinx/_static/github_issue_links.css new file mode 100644 index 000000000..af4be86ce --- /dev/null +++ b/docs/.sphinx/_static/github_issue_links.css @@ -0,0 +1,24 @@ +.github-issue-link-container { + padding-right: 0.5rem; +} +.github-issue-link { + font-size: var(--font-size--small); + font-weight: bold; + background-color: #DD4814; + padding: 13px 23px; + text-decoration: none; +} +.github-issue-link:link { + color: #FFFFFF; +} +.github-issue-link:visited { + color: #FFFFFF +} +.muted-link.github-issue-link:hover { + color: #FFFFFF; + text-decoration: underline; +} +.github-issue-link:active { + color: #FFFFFF; + text-decoration: underline; +} diff --git a/docs/.sphinx/_static/github_issue_links.js b/docs/.sphinx/_static/github_issue_links.js new file mode 100644 index 000000000..980609cd0 --- /dev/null +++ b/docs/.sphinx/_static/github_issue_links.js @@ -0,0 +1,26 @@ +window.onload = function() { + const link = document.createElement("a"); + link.classList.add("muted-link"); + link.classList.add("github-issue-link"); + link.text = "Give feedback"; + link.href = ( + github_url + + "/issues/new?" + + "title=docs%3A+TYPE+YOUR+QUESTION+HERE" + + "&body=*Please describe the question or issue you're facing with " + + `"${document.title}"` + + ".*" + + "%0A%0A%0A%0A%0A" + + "---" + + "%0A" + + `*Reported+from%3A+${location.href}*` + ); + link.target = "_blank"; + + const div = document.createElement("div"); + div.classList.add("github-issue-link-container"); + div.append(link) + + const container = document.querySelector(".article-container > .content-icon-container"); + container.prepend(div); +}; diff --git a/docs/.sphinx/_static/header-nav.js b/docs/.sphinx/_static/header-nav.js new file mode 100644 index 000000000..3608576e0 --- /dev/null +++ b/docs/.sphinx/_static/header-nav.js @@ -0,0 +1,10 @@ +$(document).ready(function() { + $(document).on("click", function () { + $(".more-links-dropdown").hide(); + }); + + $('.nav-more-links').click(function(event) { + $('.more-links-dropdown').toggle(); + event.stopPropagation(); + }); +}) diff --git a/docs/.sphinx/_static/header.css b/docs/.sphinx/_static/header.css new file mode 100644 index 000000000..0b9440903 --- /dev/null +++ b/docs/.sphinx/_static/header.css @@ -0,0 +1,167 @@ +.p-navigation { + border-bottom: 1px solid var(--color-sidebar-background-border); +} + +.p-navigation__nav { + background: #333333; + display: flex; +} + +.p-logo { + display: flex !important; + padding-top: 0 !important; + text-decoration: none; +} + +.p-logo-image { + height: 44px; + padding-right: 10px; +} + +.p-logo-text { + margin-top: 18px; + color: white; + text-decoration: none; +} + +ul.p-navigation__links { + display: flex; + list-style: none; + margin-left: 0; + margin-top: auto; + margin-bottom: auto; + max-width: 800px; + width: 100%; +} + +ul.p-navigation__links li { + margin: 0 auto; + text-align: center; + width: 100%; +} + +ul.p-navigation__links li a { + background-color: rgba(0, 0, 0, 0); + border: none; + border-radius: 0; + color: var(--color-sidebar-link-text); + display: block; + font-weight: 400; + line-height: 1.5rem; + margin: 0; + overflow: hidden; + padding: 1rem 0; + position: relative; + text-align: left; + text-overflow: ellipsis; + transition-duration: .1s; + transition-property: background-color, color, opacity; + transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + white-space: nowrap; + width: 100%; +} + +ul.p-navigation__links .p-navigation__link { + color: #ffffff; + font-weight: 300; + text-align: center; + text-decoration: none; +} + +ul.p-navigation__links .p-navigation__link:hover { + background-color: #2b2b2b; +} + +ul.p-navigation__links .p-dropdown__link:hover { + background-color: var(--color-sidebar-item-background--hover); +} + +ul.p-navigation__links .p-navigation__sub-link { + background: var(--color-background-primary); + padding: .5rem 0 .5rem .5rem; + font-weight: 300; +} + +ul.p-navigation__links .more-links-dropdown li a { + border-left: 1px solid var(--color-sidebar-background-border); + border-right: 1px solid var(--color-sidebar-background-border); +} + +ul.p-navigation__links .more-links-dropdown li:first-child a { + border-top: 1px solid var(--color-sidebar-background-border); +} + +ul.p-navigation__links .more-links-dropdown li:last-child a { + border-bottom: 1px solid var(--color-sidebar-background-border); +} + +ul.p-navigation__links .p-navigation__logo { + padding: 0.5rem; +} + +ul.p-navigation__links .p-navigation__logo img { + width: 40px; +} + +ul.more-links-dropdown { + display: none; + overflow-x: visible; + height: 0; + z-index: 55; + padding: 0; + position: relative; + list-style: none; + margin-bottom: 0; + margin-top: 0; +} + +.nav-more-links::after { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath fill='%23111' d='M8.187 11.748l6.187-6.187-1.06-1.061-5.127 5.127L3.061 4.5 2 5.561z'/%3E%3C/svg%3E"); + background-position: center; + background-repeat: no-repeat; + background-size: contain; + content: ""; + display: block; + filter: invert(100%); + height: 1rem; + pointer-events: none; + position: absolute; + right: 1rem; + text-indent: calc(100% + 10rem); + top: calc(1rem + 0.25rem); + width: 1rem; +} + +.nav-ubuntu-com { + display: none; +} + +@media only screen and (min-width: 480px) { + ul.p-navigation__links li { + width: 100%; + } + + .nav-ubuntu-com { + display: inherit; + } +} + +@media only screen and (max-width: 800px) { + .nav-more-links { + margin-left: auto !important; + padding-right: 2rem !important; + width: 8rem !important; + } +} + +@media only screen and (min-width: 800px) { + ul.p-navigation__links li { + width: 100% !important; + } +} + +@media only screen and (min-width: 1310px) { + ul.p-navigation__links { + margin-left: calc(50% - 41em); + } +} diff --git a/docs/.sphinx/_static/tag.png b/docs/.sphinx/_static/tag.png new file mode 100644 index 000000000..f6f6e5aa4 Binary files /dev/null and b/docs/.sphinx/_static/tag.png differ diff --git a/docs/.sphinx/_templates/base.html b/docs/.sphinx/_templates/base.html new file mode 100644 index 000000000..62ffe6b8c --- /dev/null +++ b/docs/.sphinx/_templates/base.html @@ -0,0 +1,7 @@ +{% extends "furo/base.html" %} + +{% block theme_scripts %} + +{% endblock theme_scripts %} diff --git a/docs/.sphinx/_templates/footer.html b/docs/.sphinx/_templates/footer.html new file mode 100644 index 000000000..759448687 --- /dev/null +++ b/docs/.sphinx/_templates/footer.html @@ -0,0 +1,90 @@ +{# ru-fu: copied from Furo, with modifications as stated below #} + + +
+
+ {%- if show_copyright %} + + {%- endif %} + + {# ru-fu: removed "Made with" #} + + {%- if last_updated -%} +
+ {% trans last_updated=last_updated|e -%} + Last updated on {{ last_updated }} + {%- endtrans -%} +
+ {%- endif %} + + {%- if show_source and has_source and sourcename %} + + {%- endif %} +
+
+ + {# ru-fu: replaced RTD icons with our links #} + + {% if discourse %} + + {% endif %} + + {% if github_url and github_version and github_folder %} + + {% if github_issues %} + + {% endif %} + + + {% endif %} + + +
+
+ diff --git a/docs/.sphinx/_templates/header.html b/docs/.sphinx/_templates/header.html new file mode 100644 index 000000000..1a128b6f8 --- /dev/null +++ b/docs/.sphinx/_templates/header.html @@ -0,0 +1,36 @@ + diff --git a/docs/.sphinx/_templates/page.html b/docs/.sphinx/_templates/page.html new file mode 100644 index 000000000..bda306109 --- /dev/null +++ b/docs/.sphinx/_templates/page.html @@ -0,0 +1,49 @@ +{% extends "furo/page.html" %} + +{% block footer %} + {% include "footer.html" %} +{% endblock footer %} + +{% block body -%} + {% include "header.html" %} + {{ super() }} +{%- endblock body %} + +{% if meta and ((meta.discourse and discourse_prefix) or meta.relatedlinks) %} + {% set furo_hide_toc_orig = furo_hide_toc %} + {% set furo_hide_toc=false %} +{% endif %} + +{% block right_sidebar %} +
+ {% if not furo_hide_toc_orig %} +
+ + {{ _("Contents") }} + +
+
+
+ {{ toc }} +
+
+ {% endif %} + {% if meta and ((meta.discourse and discourse_prefix) or meta.relatedlinks) %} + + + {% endif %} +
+{% endblock right_sidebar %} diff --git a/docs/.sphinx/requirements.txt b/docs/.sphinx/requirements.txt new file mode 100644 index 000000000..d6f37e04b --- /dev/null +++ b/docs/.sphinx/requirements.txt @@ -0,0 +1,13 @@ +sphinx +sphinx-autobuild +sphinx-design +furo +sphinx-tabs +sphinx-reredirects +pyspelling +sphinxext-opengraph +lxd-sphinx-extensions +sphinx-copybutton +myst-parser +sphinxcontrib-jquery +sphinx-notfound-page diff --git a/docs/.sphinx/spellingcheck.yaml b/docs/.sphinx/spellingcheck.yaml new file mode 100644 index 000000000..b007590ea --- /dev/null +++ b/docs/.sphinx/spellingcheck.yaml @@ -0,0 +1,27 @@ +matrix: +- name: rST files + aspell: + lang: en + d: en_US + dictionary: + wordlists: + - .wordlist.txt + output: .sphinx/.wordlist.dic + sources: + - _build/**/*.html + pipeline: + - pyspelling.filters.html: + comments: false + attributes: + - title + - alt + ignores: + - code + - pre + - spellexception + - link + - title + - div.relatedlinks + - div.visually-hidden + - img + - a.p-navigation__link diff --git a/docs/.wokeignore b/docs/.wokeignore new file mode 100644 index 000000000..c64a60376 --- /dev/null +++ b/docs/.wokeignore @@ -0,0 +1,4 @@ +# the cheat sheets contain a link to a repository with a block word which we +# cannot avoid for now, ie +# https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html +doc-cheat-sheet* diff --git a/docs/.wordlist.txt b/docs/.wordlist.txt new file mode 100644 index 000000000..4a57c5403 --- /dev/null +++ b/docs/.wordlist.txt @@ -0,0 +1,115 @@ +Acknowledgements +adml +ADML +admx +ADMX +adsys +ADSys +adsysctl +adsysd +adwatchd +APIs +apparmor +AppArmor +AppArmor's +autocompletion +autoenroll +autoenrollment +autoload +backend +backends +CAs +CEP +CES +changelog +CLI +compinit +config +constructiveCAs +CSR +dconf +Diátaxis +dir +Dropdown +enrolment +erroring +executables +favicon +fpath +FQDN +GDM +GPL +GPO +gpolist +GPOs +GPT +GSettings +GVfs +html +https +idempotency +IIS +incrementation +incrementing +infos +ini +installable +ip +Jira +kerberos +Kerberos +LDAP +lifecycle +LTS +MacOS +macOS +Makefile +multiline +MyST +namespace +OpenLDAP +OU +OUs +Permalink +polkit +powershell +PowerShell +pre +ReadMe +readthedocs +reST +reStructuredText +RTD +runscripts +sss +sssd +SSSD +subcommands +subdirectories +subdirectory +subprofile +subprofiles +subtree +sudo +syntaxes +systemd +systemd's +sysvol +TDB +TODO +toolset +Transactional +txt +ubuntu +UI +Unix +unmonitoring +unmount +unmounting +Unmounting +unticking +vendoring +Winbind +yaml +zsh +zshrc diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 000000000..c85dcc5c2 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,121 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SPHINXDIR = .sphinx +SOURCEDIR = . +BUILDDIR = _build +VENVDIR = $(SPHINXDIR)/venv +VENV = $(VENVDIR)/bin/activate + + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help + +# Explicit target avoids fall-through to the "Makefile" target. +$(SPHINXDIR)/requirements.txt: + test -f $(SPHINXDIR)/requirements.txt + +# If requirements are updated, venv should be rebuilt and timestamped. +$(VENVDIR): $(SPHINXDIR)/requirements.txt + @echo "... setting up virtualenv" + python3 -m venv $(VENVDIR) + . $(VENV); pip install --upgrade -r $(SPHINXDIR)/requirements.txt + @echo "\n" \ + "--------------------------------------------------------------- \n" \ + "* watch, build and serve the documentation: make run \n" \ + "* only build: make html \n" \ + "* only serve: make serve \n" \ + "* clean built doc files: make clean-doc \n" \ + "* clean full environment: make clean \n" \ + "* check spelling: make spelling \n" \ + "* check inclusive language: make woke \n" \ + "* other possible targets: make \n" \ + "--------------------------------------------------------------- \n" + @touch $(VENVDIR) + + +woke-install: + @type woke >/dev/null 2>&1 || \ + { echo "Installing \"woke\" snap... \n"; sudo snap install woke; } + +.PHONY: woke-install + + +install: $(VENVDIR) woke-install + +.PHONY: install + + +run: install + . $(VENV); sphinx-autobuild -c . -b dirhtml "$(SOURCEDIR)" "$(BUILDDIR)" + +.PHONY: run + +# Doesn't depend on $(BUILDDIR) to rebuild properly at every run. +html: install + . $(VENV); $(SPHINXBUILD) -c . -b dirhtml "$(SOURCEDIR)" "$(BUILDDIR)" \ + -w .sphinx/warnings.txt + +.PHONY: html + + +epub: install + . $(VENV); $(SPHINXBUILD) -c . -b epub "$(SOURCEDIR)" "$(BUILDDIR)" \ + -w .sphinx/warnings.txt + +.PHONY: epub + + +serve: html + cd "$(BUILDDIR)"; python3 -m http.server 8000 + +.PHONY: serve + + +clean: clean-doc + @test ! -e "$(VENVDIR)" -o \ + -d "$(VENVDIR)" -a "$(abspath $(VENVDIR))" != "$(VENVDIR)" + rm -rf $(VENVDIR) + +.PHONY: clean + + +clean-doc: + git clean -fx "$(BUILDDIR)" + +.PHONY: clean-doc + + +spelling: html + . $(VENV) ; python3 -m pyspelling -c .sphinx/spellingcheck.yaml + +.PHONY: spelling + + +linkcheck: install + . $(VENV) ; $(SPHINXBUILD) -c . -b linkcheck "$(SOURCEDIR)" "$(BUILDDIR)" + +.PHONY: linkcheck + + +woke: woke-install + woke *.rst **/*.rst \ + -c https://github.com/canonical/Inclusive-naming/raw/main/config.yml + +.PHONY: woke + + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + . $(VENV); \ + $(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: Makefile diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 000000000..be11d82f1 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,182 @@ +import sys + +sys.path.append('./') +from custom_conf import * + +# Configuration file for the Sphinx documentation builder. +# You should not do any modifications to this file. Put your custom +# configuration into the custom_conf.py file. +# If you need to change this file, contribute the changes upstream. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +############################################################ +### Extensions +############################################################ + +extensions = [ + 'sphinx_design', + 'sphinx_tabs.tabs', + 'sphinx_reredirects', + 'youtube-links', + 'related-links', + 'custom-rst-roles', + 'terminal-output', + 'sphinx_copybutton', + 'sphinxext.opengraph', + 'myst_parser', + 'sphinxcontrib.jquery', + 'notfound.extension' +] +extensions.extend(custom_extensions) + +### Configuration for extensions + +# Additional MyST syntax +myst_enable_extensions = [ + 'substitution', + 'deflist' +] + +# Used for related links +if 'discourse' in html_context: + html_context['discourse_prefix'] = html_context['discourse'] + '/t/' + +# The default for notfound_urls_prefix usually works, but not for +# documentation on documentation.ubuntu.com +if slug: + notfound_urls_prefix = '/' + slug + '/en/latest/' + +notfound_context = { + 'title': 'Page not found', + 'body': '

Page not found

\n\n

Sorry, but the documentation page that you are looking for was not found.

\n

Documentation changes over time, and pages are moved around. We try to redirect you to the updated content where possible, but unfortunately, that didn\'t work this time (maybe because the content you were looking for does not exist in this version of the documentation).

\n

You can try to use the navigation to locate the content you\'re looking for, or search for a similar page.

\n', +} + +# Default image for OGP (to prevent font errors, see +# https://github.com/canonical/sphinx-docs-starter-pack/pull/54 ) +if not 'ogp_image' in locals(): + ogp_image = 'https://assets.ubuntu.com/v1/253da317-image-document-ubuntudocs.svg' + +############################################################ +### General configuration +############################################################ + +exclude_patterns = [ + '_build', + 'Thumbs.db', + '.DS_Store', + '.sphinx', + 'doc-cheat-sheet*', +] +exclude_patterns.extend(custom_excludes) + +rst_epilog = ''' +.. include:: /reuse/links.txt +''' +if 'custom_rst_epilog' in locals(): + rst_epilog = custom_rst_epilog + +source_suffix = { + '.rst': 'restructuredtext', + '.md': 'markdown', +} + +if not 'conf_py_path' in html_context and 'github_folder' in html_context: + html_context['conf_py_path'] = html_context['github_folder'] + +# For ignoring specific links +linkcheck_anchors_ignore_for_url = [ + r'https://github\.com/.*' +] + +############################################################ +### Styling +############################################################ + +# Find the current builder +builder = 'dirhtml' +if '-b' in sys.argv: + builder = sys.argv[sys.argv.index('-b')+1] + +# Setting templates_path for epub makes the build fail +if builder == 'dirhtml' or builder == 'html': + templates_path = ['.sphinx/_templates'] + +# Theme configuration +html_theme = 'furo' +html_last_updated_fmt = '' +html_permalinks_icon = '¶' +html_theme_options = { + 'light_css_variables': { + 'font-stack': 'Ubuntu, -apple-system, Segoe UI, Roboto, Oxygen, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif', + 'font-stack--monospace': 'Ubuntu Mono, Consolas, Monaco, Courier, monospace', + 'color-foreground-primary': '#111', + 'color-foreground-secondary': 'var(--color-foreground-primary)', + 'color-foreground-muted': '#333', + 'color-background-secondary': '#FFF', + 'color-background-hover': '#f2f2f2', + 'color-brand-primary': '#111', + 'color-brand-content': '#06C', + 'color-api-background': '#cdcdcd', + 'color-inline-code-background': 'rgba(0,0,0,.03)', + 'color-sidebar-link-text': '#111', + 'color-sidebar-item-background--current': '#ebebeb', + 'color-sidebar-item-background--hover': '#f2f2f2', + 'toc-font-size': 'var(--font-size--small)', + 'color-admonition-title-background--note': 'var(--color-background-primary)', + 'color-admonition-title-background--tip': 'var(--color-background-primary)', + 'color-admonition-title-background--important': 'var(--color-background-primary)', + 'color-admonition-title-background--caution': 'var(--color-background-primary)', + 'color-admonition-title--note': '#24598F', + 'color-admonition-title--tip': '#24598F', + 'color-admonition-title--important': '#C7162B', + 'color-admonition-title--caution': '#F99B11', + 'color-highlighted-background': '#EbEbEb', + 'color-link-underline': 'var(--color-background-primary)', + 'color-link-underline--hover': 'var(--color-background-primary)', + 'color-version-popup': '#772953' + }, + 'dark_css_variables': { + 'color-foreground-secondary': 'var(--color-foreground-primary)', + 'color-foreground-muted': '#CDCDCD', + 'color-background-secondary': 'var(--color-background-primary)', + 'color-background-hover': '#666', + 'color-brand-primary': '#fff', + 'color-brand-content': '#06C', + 'color-sidebar-link-text': '#f7f7f7', + 'color-sidebar-item-background--current': '#666', + 'color-sidebar-item-background--hover': '#333', + 'color-admonition-background': 'transparent', + 'color-admonition-title-background--note': 'var(--color-background-primary)', + 'color-admonition-title-background--tip': 'var(--color-background-primary)', + 'color-admonition-title-background--important': 'var(--color-background-primary)', + 'color-admonition-title-background--caution': 'var(--color-background-primary)', + 'color-admonition-title--note': '#24598F', + 'color-admonition-title--tip': '#24598F', + 'color-admonition-title--important': '#C7162B', + 'color-admonition-title--caution': '#F99B11', + 'color-highlighted-background': '#666', + 'color-link-underline': 'var(--color-background-primary)', + 'color-link-underline--hover': 'var(--color-background-primary)', + 'color-version-popup': '#F29879' + }, +} + +############################################################ +### Additional files +############################################################ + +html_static_path = ['.sphinx/_static'] + +html_css_files = [ + 'custom.css', + 'header.css', + 'github_issue_links.css', +] +html_css_files.extend(custom_html_css_files) + +html_js_files = ['header-nav.js'] +if 'github_issues' in html_context and html_context['github_issues'] and not disable_feedback_button: + html_js_files.append('github_issue_links.js') +html_js_files.extend(custom_html_js_files) diff --git a/docs/custom_conf.py b/docs/custom_conf.py new file mode 100644 index 000000000..205a3a617 --- /dev/null +++ b/docs/custom_conf.py @@ -0,0 +1,139 @@ +import datetime + +# Custom configuration for the Sphinx documentation builder. +# All configuration specific to your project should be done in this file. +# +# The file is included in the common conf.py configuration file. +# You can modify any of the settings below or add any configuration that +# is not covered by the common conf.py file. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +############################################################ +### Project information +############################################################ + +# Product name +project = 'Active Directory GPO support' +author = 'Canonical Group Ltd' + +# Uncomment if your product uses release numbers +# release = '0.13.0' + +# The default value uses the current year as the copyright year. +# +# For static works, it is common to provide the year of first publication. +# Another option is to give the first year and the current year +# for documentation that is often changed, e.g. 2022–2023 (note the en-dash). +# +# A way to check a GitHub repo's creation date is to obtain a classic GitHub +# token with 'repo' permissions here: https://github.com/settings/tokens +# Next, use 'curl' and 'jq' to extract the date from the GitHub API's output: +# +# curl -H 'Authorization: token ' \ +# -H 'Accept: application/vnd.github.v3.raw' \ +# https://api.github.com/repos/canonical/ | jq '.created_at' + +copyright = '%s, %s' % (datetime.date.today().year, author) + +## Open Graph configuration - defines what is displayed in the website preview +# The URL of the documentation output +ogp_site_url = 'https://canonical-starter-pack.readthedocs-hosted.com/' +# The documentation website name (usually the same as the product name) +ogp_site_name = project +# An image or logo that is used in the preview +ogp_image = 'https://assets.ubuntu.com/v1/253da317-image-document-ubuntudocs.svg' + +# Update with the favicon for your product (default is the circle of friends) +html_favicon = '.sphinx/_static/favicon.png' + +# (Some settings must be part of the html_context dictionary, while others +# are on root level. Don't move the settings.) +html_context = { + + # Change to the link to your product website (without "https://") + 'product_page': 'github.com/ubuntu/adsys', + + # Add your product tag to ".sphinx/_static" and change the path + # here (start with "_static"), default is the circle of friends + 'product_tag': '_static/tag.png', + + # Change to the discourse instance you want to be able to link to + # using the :discourse: metadata at the top of a file + # (use an empty value if you don't want to link) + 'discourse': 'https://discourse.ubuntu.com', + + # Change to the GitHub info for your project + 'github_url': 'https://github.com/ubuntu/adsys', + + # Change to the branch for this version of the documentation + 'github_version': 'main', + + # Change to the folder that contains the documentation + # (usually "/" or "/docs/") + 'github_folder': '/docs/', + + # Change to an empty value if your GitHub repo doesn't have issues enabled. + # This will disable the feedback button and the issue link in the footer. + 'github_issues': 'enabled' +} + +# If your project is on documentation.ubuntu.com, specify the project +# slug (for example, "lxd") here. +slug = "" + +############################################################ +### Redirects +############################################################ + +# Set up redirects (https://documatt.gitlab.io/sphinx-reredirects/usage.html) +# For example: 'explanation/old-name.html': '../how-to/prettify.html', + +redirects = {} + +############################################################ +### Link checker exceptions +############################################################ + +# Links to ignore when checking links + +linkcheck_ignore = [ + 'http://127.0.0.1:8000' + ] + +############################################################ +### Additions to default configuration +############################################################ + +## The following settings are appended to the default configuration. +## Use them to extend the default functionality. + +# Add extensions +custom_extensions = [] + +# Add files or directories that should be excluded from processing. +custom_excludes = [] + +# Add CSS files (located in .sphinx/_static/) +custom_html_css_files = [] + +# Add JavaScript files (located in .sphinx/_static/) +custom_html_js_files = [] + +## The following settings override the default configuration. + +# Specify a reST string that is included at the end of each file. +# If commented out, use the default (which pulls the reuse/links.txt +# file into each reST file). +# custom_rst_epilog = '' + +# By default, the documentation includes a feedback button at the top. +# You can disable it by setting the following configuration to True. +disable_feedback_button = False + +############################################################ +### Additional configuration +############################################################ + +## Add any configuration that is not covered by the common conf.py file. diff --git a/docs/docs.go b/docs/docs.go new file mode 100644 index 000000000..2c04a20d0 --- /dev/null +++ b/docs/docs.go @@ -0,0 +1,15 @@ +// Package docs embeds structured adsys documentation. +package docs + +import ( + "embed" +) + +// Dir is the embedded directory containing documentation. +// Only embed structured documentation. +// +//go:embed index.md tutorial/*.md how-to/*.md explanation/*.md reference/*.md +var Dir embed.FS + +// RTDRootURL is the root url of ReadTheDoc adsys documentation. +const RTDRootURL = "https://canonical-adsys.readthedocs-hosted.com/en/documentation_bootstrap" diff --git a/doc/08.-Managing-apparmor-profiles.md b/docs/explanation/apparmor.md similarity index 86% rename from doc/08.-Managing-apparmor-profiles.md rename to docs/explanation/apparmor.md index 79e3d1066..eb0f62a84 100644 --- a/doc/08.-Managing-apparmor-profiles.md +++ b/docs/explanation/apparmor.md @@ -23,7 +23,7 @@ AppArmor profiles must be available in the assets sharing directory on your Acti In this directory, next to `Policies` in your domain folder, create a directory matching your distribution name. For instance `Ubuntu`, which will be the assets sharing directory. -![Assets folder in sysvol](images/Scripts-execution/assets-folder.png) +![Assets folder in sysvol](../images/explanation/apparmor/assets-folder.png) It must also contain a `GPT.ini` file of the form: @@ -39,23 +39,23 @@ Then, place any AppArmor profiles you need under the `apparmor/` directory (subd ### Automating the incrementation of the `GPT.ini` version stanza -Making manual changes to a file everytime AppArmor profiles are changed can be unproductive and tedious. For your convenience, we developed a tool to automate this process. For detailed usage and installation instructions please refer to the [Active Directory Watch Daemon](14.-Active-Directory-Watch-Daemon.md) documentation. +Making manual changes to a file every time AppArmor profiles are changed can be unproductive and tedious. For your convenience, we developed a tool to automate this process. For detailed usage and installation instructions please refer to the [Active Directory Watch Daemon](../reference/adwatchd) documentation. ## Developing AppArmor profiles We highly recommend developing AppArmor profiles separately from ADSys, testing them, and only then integrating them with ADSys. Here are some resources to get you started: -- https://ubuntu.com/tutorials/beginning-apparmor-profile-development#1-overview -- https://gitlab.com/apparmor/apparmor/-/wikis/Documentation -- https://medium.com/information-and-technology/so-what-is-apparmor-64d7ae211ed +* [How to create AppArmor Profile](https://ubuntu.com/tutorials/beginning-apparmor-profile-development#1-overview) +* [AppArmor Documentation](https://gitlab.com/apparmor/apparmor/-/wikis/Documentation) +* [The Comprehensive Guide To AppArmor](https://medium.com/information-and-technology/so-what-is-apparmor-64d7ae211ed) ## System-wide profiles -The form is a list of AppArmor profile paths, relative to the `apparmor/` subdirectory of your assets sharing filesystem, one per line. +The form is a list of AppArmor profile paths, relative to the `apparmor/` subdirectory of your assets sharing file system, one per line. -![List of machine profiles example](images/Managing-AppArmor-profiles/apparmor-machine-ui.png) +![List of machine profiles example](../images/explanation/apparmor/apparmor-machine-ui.png) -When set to enabled, adsys will load the configured AppArmor profiles on refresh. AppArmor's caching functionality is leveraged to ensure redundant reloads are kept to a minimum, i.e. a loaded profile will be reparsed only if a change occurred in the profile definition. +When set to enabled, adsys will load the configured AppArmor profiles on refresh. AppArmor's caching functionality is leveraged to ensure redundant reloads are kept to a minimum, i.e. a loaded profile will be parsed again only if a change occurred in the profile definition. On the client machine, system-wide profiles are located under `/etc/apparmor.d/adsys/machine` by default. @@ -65,20 +65,21 @@ When set disabled / not configured, ADSys will unload any previously loaded prof AppArmor supports confining executables on a user-by-user basis via the [`pam_apparmor` PAM module](https://gitlab.com/apparmor/apparmor/-/wikis/Pam_apparmor). The module allows applications to confine authenticated users into subprofiles based on group names, user names, or a default profile. To accomplish this, `pam_apparmor` needs to be registered as a PAM session module. A [working example](https://gitlab.com/apparmor/apparmor/-/wikis/Pam_apparmor_example) can be found on the official AppArmor repository wiki. -The form accepts a path to a single file, relative to the `apparmor/` directory of your assets sharing filesystem. +The form accepts a path to a single file, relative to the `apparmor/` directory of your assets sharing file system. -![User profile entry example](images/Managing-AppArmor-profiles/apparmor-user-ui.png) +![User profile entry example](../images/explanation/apparmor/apparmor-user-ui.png) ### Installing the AppArmor PAM module The PAM module can be installed on Ubuntu using the following command: -``` + +```sh sudo apt install libpam-apparmor ``` The module must then be configured manually for any desired executables. To enable it for the `su` command, append the following to the `/etc/pam.d/su` file: -``` +```sh session optional pam_apparmor.so order=user,default ``` @@ -91,7 +92,7 @@ As per the example linked above, the user profile is essentially a subprofile (a If a regular subprofile looks like the following (assuming `admin@domain.com` is the user we want to confine): -```apparmor +```bnf ^admin@domain.com { #include #include @@ -108,7 +109,7 @@ If a regular subprofile looks like the following (assuming `admin@domain.com` is Its ADSys counterpart will omit the first and last lines which will be inferred automatically when policies are applied on the client machine. Thus, the subprofile declaration becomes: -```apparmor +```bnf #include #include capability dac_override, @@ -127,7 +128,7 @@ The user profile doesn't accomplish anything on its own until it is included in It is also recommended to define a `DEFAULT` subprofile as part of the system-wide profiles to ensure `pam_apparmor` has a profile to switch to as a last resort if it cannot find a profile for the user. -```apparmor +```bnf /usr/bin/su { ... include "users" @@ -145,20 +146,20 @@ It is also recommended to define a `DEFAULT` subprofile as part of the system-wi } ``` -## Profile parsing behaviours +## Profile parsing behaviors ### Troubleshooting misbehaving user profiles If you encounter issues with user profiles, it's always helpful to check the kernel buffer (`dmesg`) and the authentication logs at `/var/log/auth.log`. Additionally, appending `debug` to the PAM module declaration stanzas at `/etc/pam.d/` will log additional debug information, such as the profile that the module tries to switch to. -``` +```output Nov 18 13:55:48 ubuntu2204 su: pam_unix(su:session): session opened for user administrator@warthogs.biz(uid=1130200500) by root(uid=0) Nov 18 13:55:48 ubuntu2204 su: pam_apparmor(su:session): Using username 'administrator@warthogs.biz' ``` In contrast, switching to a user with no declared profile and no default profile will print the following and restrict access entirely: -``` +```output Nov 18 14:00:22 ubuntu2204 su: pam_unix(su:session): session opened for user fry@warthogs.biz(uid=1130201105) by root(uid=0) Nov 18 14:00:22 ubuntu2204 su: pam_apparmor(su:session): Using username 'fry@warthogs.biz' Nov 18 14:00:22 ubuntu2204 su: pam_apparmor(su:session): Using DEFAULT @@ -172,9 +173,9 @@ The PAM module goes through the order specified in the configuration (user, defa ADSys relies on the `apparmor_parser` executable to parse, load, and unload profiles. If the command fails for any reason (e.g. syntax errors in profile declaration), loading profiles will be aborted and the output of the `apparmor_parser` command will be logged. -``` +```output ERROR Error from server: error while updating policy: failed to apply policy to "ubuntu2204": can't apply apparmor policy to ubuntu2204: can't apply machine policy: failed to get apparmor policies: exit status 1 -AppArmor parser error for /etc/apparmor.d/adsys/machine/pam_roles in profile /etc/apparmor.d/adsys/machine/pam_roles at line 9: Lexer found unexpected character: '<' (0x3c) in state: INITIAL +AppArmor parser error for /etc/apparmor.d/adsys/machine/pam_roles in profile /etc/apparmor.d/adsys/machine/pam_roles at line 9: Lexer found unexpected character: '<' (0x3c) in state: INITIAL ``` ### Invalid profile path reference diff --git a/doc/11.-Certificate-autoenrollment.md b/docs/explanation/certificates.md similarity index 71% rename from doc/11.-Certificate-autoenrollment.md rename to docs/explanation/certificates.md index 5e022dbe2..945e2b1d2 100644 --- a/doc/11.-Certificate-autoenrollment.md +++ b/docs/explanation/certificates.md @@ -6,7 +6,7 @@ Unlike the other ADSys policy managers which are configured in the special Ubunt * Computer Configuration > Policies > Windows Settings > Security Settings > Public Key Policies > Certificate Services Client - Auto-Enrollment -![Certificate GPO tree view](images/Certificate-auto-enrollment/certificate-settings.png) +![Certificate GPO tree view](../images/explanation/certificates/certificate-settings.png) ## Feature availability @@ -14,19 +14,21 @@ This feature is available only for subscribers of **Ubuntu Pro** and has been te Additionally, the following packages must be installed on the client in order for auto-enrollment to work: -- [`certmonger`](https://www.freeipa.org/page/Certmonger) - daemon that monitors and updates certificates -- [`cepces`](https://github.com/openSUSE/cepces) - `certmonger` extension that can communicate with **Active Directory Certificate Services** +* [`certmonger`](https://www.freeipa.org/page/Certmonger) - daemon that monitors and updates certificates +* [`cepces`](https://github.com/openSUSE/cepces) - `certmonger` extension that can communicate with **Active Directory Certificate Services** On Ubuntu systems, run the following to install them: -```sh + +```bash sudo apt install certmonger python3-cepces ``` On the Windows side, the following roles must be installed and configured: -- Certification Authority -- Certificate Enrollment Policy Web Service -- Certificate Enrollment Web Service -- Network Device Enrollment Service + +* Certification Authority +* Certificate Enrollment Policy Web Service +* Certificate Enrollment Web Service +* Network Device Enrollment Service ## Rules precedence @@ -36,59 +38,62 @@ Auto-enrollment configuration will override any settings referenced higher in th Certificate auto-enrollment is configured by setting the **Configuration Model** to **Enabled** and ticking the following checkbox: **Update certificates that use certificate templates**. -![Certificate GPO properties](images/Certificate-auto-enrollment/certificate-gpo.png) +![Certificate GPO properties](../images/explanation/certificates/certificate-gpo.png) The policy can be disabled by performing _any_ of the following: -- unticking the **Update certificates that use certificate templates** checkbox -- setting the **Configuration Model** to **Disabled** or **Not configured** + +* unticking the **Update certificates that use certificate templates** checkbox +* setting the **Configuration Model** to **Disabled** or **Not configured** The other settings in this GPO entry do not affect ADSys in any way. For more advanced configuration, a list of policy servers can be specified in the following GPO entry: + * Computer Configuration > Policies > Windows Settings > Security Settings > Public Key Policies > Certificate Services Client - Certificate Enrollment Policy -![Certificate advanced configuration](images/Certificate-auto-enrollment/advanced-configuration.png) +![Certificate advanced configuration](../images/explanation/certificates/advanced-configuration.png) ## Applying the policy On the client system, a successful auto-enrollment will place certificate data in the following paths: -- `/var/lib/adsys/certs` - certificate data -- `/var/lib/adsys/private/certs` - private key data -- `/usr/local/share/ca-certificates` - root certificate data (symlinks pointing to `/var/lib/adsys/certs`) + +* `/var/lib/adsys/certs` - certificate data +* `/var/lib/adsys/private/certs` - private key data +* `/usr/local/share/ca-certificates` - root certificate data (symbolic link pointing to `/var/lib/adsys/certs`) For detailed information on the tracked certificates, `certmonger` can be directly interacted with: -```sh-session +```output # Query monitored certificates > getcert list Number of certificates and requests being tracked: 1. Request ID 'galacticcafe-CA.Machine': - status: MONITORING - stuck: no - key pair storage: type=FILE,location='/var/lib/adsys/private/certs/galacticcafe-CA.Machine.key' - certificate: type=FILE,location='/var/lib/adsys/certs/galacticcafe-CA.Machine.crt' - CA: galacticcafe-CA - issuer: CN=galacticcafe-CA,DC=galacticcafe,DC=com - subject: CN=keypress.galacticcafe.com - issued: 2023-08-18 18:44:27 EEST - expires: 2024-08-17 18:44:27 EEST - dns: keypress.galacticcafe.com - key usage: digitalSignature,keyEncipherment - eku: id-kp-clientAuth,id-kp-serverAuth - certificate template/profile: Machine - profile: Machine - pre-save command: - post-save command: - track: yes - auto-renew: yes + status: MONITORING + stuck: no + key pair storage: type=FILE,location='/var/lib/adsys/private/certs/galacticcafe-CA.Machine.key' + certificate: type=FILE,location='/var/lib/adsys/certs/galacticcafe-CA.Machine.crt' + CA: galacticcafe-CA + issuer: CN=galacticcafe-CA,DC=galacticcafe,DC=com + subject: CN=keypress.galacticcafe.com + issued: 2023-08-18 18:44:27 EEST + expires: 2024-08-17 18:44:27 EEST + dns: keypress.galacticcafe.com + key usage: digitalSignature,keyEncipherment + eku: id-kp-clientAuth,id-kp-serverAuth + certificate template/profile: Machine + profile: Machine + pre-save command: + post-save command: + track: yes + auto-renew: yes # Query known CAs > getcert list-cas (...) CA 'galacticcafe-CA': - is-default: no - ca-type: EXTERNAL - helper-location: /usr/libexec/certmonger/cepces-submit --server=win-mk85nrq26nu.galacticcafe.com --auth=Kerberos + is-default: no + ca-type: EXTERNAL + helper-location: /usr/libexec/certmonger/cepces-submit --server=win-mk85nrq26nu.galacticcafe.com --auth=Kerberos ``` ## Policy implementation @@ -98,22 +103,23 @@ With the exception of policy parsing, ADSys leverages the Samba implementation o To ensure idempotency when applying the policy, we set up a Samba [TDB cache file](https://wiki.samba.org/index.php/TDB) at `/var/lib/adsys/samba/cert_gpo_state_$(hostname).tdb` which contains various information pertaining to the enrolled certificate(s). Here is an overview of what happens during policy application: -- GPO parsing (ADSys) -- execute Python helper script (ADSys) -- fetch root CA and policy servers (Samba) -- start monitoring certificate using `certmonger` and `cepces` (Samba) + +* GPO parsing (ADSys) +* execute Python helper script (ADSys) +* fetch root CA and policy servers (Samba) +* start monitoring certificate using `certmonger` and `cepces` (Samba) ## Troubleshooting ### Some dependencies are not available in the client Ubuntu installation -While `certmonger` has been available for a while in Ubuntu, `python3-cepces` is a new package, available starting with Ubuntu 23.10 (Mantic). If unavailable on the client version, it can also be manually installed from the [source repository](https://github.com/openSUSE/cepces). The certificate policy manager only checks for the existence of the `cepces-submit` and `getcert` binaries, not their respective packages, in order to allow some wiggle room for this. +While `certmonger` has been available for a while in Ubuntu, `python3-cepces` is a new package, available starting with Ubuntu 23.10. If unavailable on the client version, it can also be manually installed from the [source repository](https://github.com/openSUSE/cepces). The certificate policy manager only checks for the existence of the `cepces-submit` and `getcert` binaries, not their respective packages, in order to allow some wiggle room for this. ### Manipulating certificates with `getcert` While not encouraged, certificates can be manipulated with the same tool. This could be helpful for debugging purposes. -```sh-session +```output # Regenerate a certificate > getcert rekey -i galacticcafe-CA.Machine Resubmitting "galacticcafe-CA.Machine" to "galacticcafe-CA". @@ -132,19 +138,22 @@ Note that tampering with certificate data outside of ADSys (e.g. manually unmoni ### Debugging auto-enroll script While certificate parsing happens in ADSys itself, enrollment is done via an embedded Python helper script. For debugging purposes, it can be dumped to the current directory and made executable by executing the following commands: -```sh-session + +```output > adsysctl policy debug cert-autoenroll-script > chmod +x ./cert-autoenroll ``` Before executing the script manually, the following environment variables have to be set: + ```sh export PYTHONPATH=/usr/share/adsys/python export KRB5CCNAME=/var/run/adsys/krb5cc/$(hostname) ``` Then, run the script passing the required arguments (the argument list is also printed in the ADSys debug logs during policy application): -```sh-session + +```output # Un-enroll machine > ./cert-autoenroll unenroll keypress galacticcafe.com --state_dir /var/lib/adsys --debug ``` @@ -158,8 +167,9 @@ The `cepces` configuration itself is batteries-included, meaning it should work ## Additional information While configuring Active Directory Certificate Services is outside the scope of the policy manager documentation, we have found the following resources to be useful: -- https://www.virtuallyboring.com/setup-microsoft-active-directory-certificate-services-ad-cs/ -- https://leonelson.com/2011/08/15/how-to-increase-your-csr-key-size-on-microsoft-iis-without-removing-the-production-certificate/ + +* [How to setup Microsoft Active Directory Certificate Services](https://www.virtuallyboring.com/setup-microsoft-active-directory-certificate-services-ad-cs/) +* [How to increase your CSR key size on Microsoft IIS without removing the production certificate?](https://leonelson.com/2011/08/15/how-to-increase-your-csr-key-size-on-microsoft-iis-without-removing-the-production-certificate/) ## Acknowledgements diff --git a/doc/05.-Dconf.md b/docs/explanation/dconf.md similarity index 89% rename from doc/05.-Dconf.md rename to docs/explanation/dconf.md index 8fc9164bb..737917478 100644 --- a/doc/05.-Dconf.md +++ b/docs/explanation/dconf.md @@ -28,17 +28,16 @@ Depending on the type of settings, appropriate widgets are displayed to the AD s Setting a key to `enabled` will apply a value to any machines or user targeted by the GPO. It allows the Active Directory administrator to enter a value that will be applied to the target object (user or machine). This setting will be enforced on the client. Only an administrator of the client system can override it, but it will be reset to the Active Directory setting on next refresh. -![Enabled setting](images/Dconf/enabled.png) +![Enabled setting](../images/explanation/dconf/enabled.png) #### Disabled Setting a key to `disabled` will prevent user updates. However, no value can be explicitly entered by the Active Directory administrator. The default value of the client system will then be used (which may differ between machines). -![Disabled setting](images/Dconf/disabled.png) +![Disabled setting](../images/explanation/dconf/disabled.png) #### Not configured Finally, `not configured` is the default state. The setting is managed as usual directly on the client and without Active Directory. -![Not configure setting](images/Dconf/not_configured.png) - +![Not configure setting](../images/explanation/dconf/not_configured.png) diff --git a/docs/explanation/index.md b/docs/explanation/index.md new file mode 100644 index 000000000..a04c3b766 --- /dev/null +++ b/docs/explanation/index.md @@ -0,0 +1,21 @@ +# Explanation + +**Discussion and clarification** of key topics. + +## Managers + +ADSys supports a wide variety of managers to configure and control various aspects of the client systems. + +Managers available with ADSys are + +```{toctree} +:titlesonly: +GSettings +Privileges Management +scripts +AppArmor Profiles +network-shares +proxy +Certificates Auto-Enrolment +Security Policy +``` diff --git a/doc/09.-Network-shares.md b/docs/explanation/network-shares.md similarity index 64% rename from doc/09.-Network-shares.md rename to docs/explanation/network-shares.md index 9c2e04b2f..ebdf443ee 100644 --- a/doc/09.-Network-shares.md +++ b/docs/explanation/network-shares.md @@ -1,6 +1,6 @@ # Network shares -The mount managers allow AD administrators to specify network shares that must be mounted in the filesystem when a client logs in. +The mount managers allow AD administrators to specify network shares that must be mounted in the file system when a client logs in. ## Feature Availability @@ -12,25 +12,25 @@ The mount process for these mounts is triggered at the moment a client logs in. All protocols supported by the [mount command](https://manpages.ubuntu.com/manpages/jammy/en/man8/mount.8.html) should work out of the box. However, the only tested ones are `smb`, `ftp` and `nfs`. -The backends for the protocols `smb` and `nfs` are automatically enabled when installing the adsys package. In order to enable the backend for `ftp` mounts, the user must install the recommended `curlftpfs` package. This behaviour is tested on Ubuntu and might differ on other Linux distributions. +The backends for the protocols `smb` and `nfs` are automatically enabled when installing the adsys package. In order to enable the backend for `ftp` mounts, the user must install the recommended `curlftpfs` package. This behavior is tested on Ubuntu and might differ on other Linux distributions. Access control and file permissions should be configured on the shared location. User mount policies are located under `Computer Configuration > Policies > Administrative Templates > Ubuntu > Client management > System Drive Mapping`, as shown in the following picture. -![Path to User Drive Mapping policy](images/Network-shares/system-mounts-policy-loc.png) +![Path to User Drive Mapping policy](../images/explanation/network-shares/system-mounts-policy-loc.png) ### Setting up the policy -The form is a list of shared drives that should be mounted for the client machine. They must follow the structure `{protocol}://{hostname or ip}/{shared location}`. +The form is a list of shared drives that should be mounted for the client machine. They must follow the structure `{protocol}://{host name or ip address}/{shared location}`. -The default mount behavior is to mount the listed shares anonymously. In order to require kerberos authentication for the mount process, the tag `[krb5]` can be added as a prefix to the listed share, i.e. `[krb5]{protocol}://{hostname or ip}/{shared location}`. +The default mount behavior is to mount the listed shares anonymously. In order to require kerberos authentication for the mount process, the tag `[krb5]` can be added as a prefix to the listed share, i.e. `[krb5]{protocol}://{host name or ip address}/{shared location}`. Additional mount options are not supported yet. All entries must be separated by a line break. -![List of user mounts example](images/Network-shares/system-mounts-list.png) +![List of user mounts example](../images/explanation/network-shares/system-mounts-list.png) ### Rules precedence @@ -38,9 +38,9 @@ The policy strategy is "append". Therefore, if multiple policies defining networ Duplicated shares will be handled. Anonymous and authenticated shares of the same location are treated as duplicates and the first one listed will take precedence over the others. -### Errored mounts +### Invalid mounts -ADSys will block the client authentication only if the policy could not be applied, i.e. listed shares could not be set up. Anything that occurs after the set up process, i.e. unreachable domain, share non-existent, among others, will only be reported as an error. Check system logs to see more about the failure details. +ADSys will block client authentication only if the policy cannot be applied, meaning that the listed shares could not be set up. Any issues that arise after the setup process, such as an unreachable domain or a non-existent share, will be reported as an error. Refer to the system logs for more details about the failures. ### Unmounting @@ -50,29 +50,29 @@ The unmounting process is handled by systemd on shutdown. The mount process for these mounts is triggered at the moment a user logs in. User mounts are accessible in the file manager and the user has the ability to unmount them manually. -Credentials authentication for mounts are disabled on adsys. Instead, authentication is done with the Kerberos ticket present on the machine. If the mount is set to anonymous, then the administrator must ensure that the shared drive supports anonymous access and that the permissions for the directory are set accordingly. +Credentials authentication for mounts are disabled on ADSys. Instead, authentication is done with the Kerberos ticket present on the machine. If the mount is set to anonymous, then the administrator must ensure that the shared drive supports anonymous access and that the permissions for the directory are set accordingly. User mount policies are located under `User Configuration > Policies > Administrative Templates > Ubuntu > Session management > User Drive Mapping`, as shown in the following picture. -![Path to User Drive Mapping policy](images/Network-shares/user-mounts-policy-loc.png) +![Path to User Drive Mapping policy](../images/explanation/network-shares/user-mounts-policy-loc.png) ### Setting up the policy -The form is a list of shared drives that should be mounted for the user. They must follow the structure {protocol}://{hostname or ip}/{shared location}. If the drive is to be mounted anonimously, the tag [anonymous] should be added as a prefix to the listed entry, i.e. [anonymous]{protocol}://{hostname or ip}/{shared location}. +The format is a list of shared drives that should be mounted for the user. They must follow the structure {protocol}://{host name or ip address}/{shared location}. If the drive is to be mounted anonymously, the tag [anonymous] should be added as a prefix to the listed entry, i.e. [anonymous]{protocol}://{host name or ip address}/{shared location}. All entries must be separated by a line break. -![List of user mounts example](images/Network-shares/user-mounts-list.png) +![List of user mounts example](../images/explanation/network-shares/user-mounts-list.png) -The mount process is handled with gvfs and it defines in which directory the shared drive will be mounted into. Usually, it's mounted under `/run/user/%U/gvfs/`. +The mount process is handled with GVfs and it defines in which directory the shared drive will be mounted into. Usually, it's mounted under `/run/user/%U/gvfs/`. ### Rules precedence The policy strategy is "append". Therefore, if multiple policies defining mount locations are to be applied to a user, all of the listed entries will be mounted. -### Errored mounts +### Invalid mounts -Should the mounting of a entry listed in the policy fail, adsys will continue through the other entries listed in the policy, mounting the ones that it can and logging the ones that could not be mounted. +If the mounting of an entry listed in the policy fails, ADSys will proceed with the other entries in the policy, mounting those it can and logging those that cannot be mounted. ### Unmounting diff --git a/doc/06.-Privileges-management.md b/docs/explanation/privileges.md similarity index 96% rename from doc/06.-Privileges-management.md rename to docs/explanation/privileges.md index 347aa7758..5b863e3f1 100644 --- a/doc/06.-Privileges-management.md +++ b/docs/explanation/privileges.md @@ -4,7 +4,7 @@ The Admin privilege manager allows to grant or revoke superuser privileges for t All those settings are globally enforced on the machine and are available at `Computer Configuration > Policies > Administrative Templates > Ubuntu > Client management > Privilege Authorization`. -![Privileges screen in AD](images/Privileges/privileges-options.png) +![Privileges screen in AD](../images/explanation/privileges/privileges-options.png) ## Feature availability diff --git a/doc/10.-Proxy-settings.md b/docs/explanation/proxy.md similarity index 87% rename from doc/10.-Proxy-settings.md rename to docs/explanation/proxy.md index eaae61342..51b9c1af7 100644 --- a/doc/10.-Proxy-settings.md +++ b/docs/explanation/proxy.md @@ -1,4 +1,4 @@ -# Proxy settings +# Network Proxy The proxy manager allows AD administrators to apply proxy settings on the clients. Currently, only system-wide proxy settings are supported. @@ -6,14 +6,15 @@ Proxy settings are configurable under the following GPO path: * System-wide level, located in `Computer Configuration > Policies > Administrative Templates > Ubuntu > Client management > System proxy configuration` -![System proxy settings in GPO editor](images/Proxy-settings/system-proxy-settings-list.png) +![System proxy settings in GPO editor](../images/explanation/proxy/system-proxy-settings-list.png) ## Feature availability This feature is available only for subscribers of **Ubuntu Pro**. Additionally, the [`ubuntu-proxy-manager`](https://github.com/ubuntu/ubuntu-proxy-manager) package must be installed in order for proxy settings to be applied on the client system. On Ubuntu systems, run the following to install the package: -```sh + +```bash sudo apt install ubuntu-proxy-manager ``` @@ -24,14 +25,15 @@ Configured proxy settings will override any settings referenced higher in the GP ## Setting up the policy The `System proxy configuration` category provides a list of configurable proxy settings: -- HTTP Proxy -- HTTPS Proxy -- FTP Proxy -- SOCKS Proxy -- Ignored hosts -- Autoconfiguration URL - -![HTTP proxy setting in GPO editor](images/Proxy-settings/system-proxy-settings-focus.png) + +* HTTP Proxy +* HTTPS Proxy +* FTP Proxy +* SOCKS Proxy +* Ignored hosts +* Auto configuration URL + +![HTTP proxy setting in GPO editor](../images/explanation/proxy/system-proxy-settings-focus.png) Configured settings will then be forwarded to `ubuntu-proxy-manager` which will apply them on all supported backends (e.g. environment variables, APT, GSettings). For an up-to-date list of supported backends, proxy formats and behaviors, refer to the ubuntu-proxy-manager [documentation](https://github.com/ubuntu/ubuntu-proxy-manager/blob/main/README.md). diff --git a/doc/07.-Scripts-execution.md b/docs/explanation/scripts.md similarity index 82% rename from doc/07.-Scripts-execution.md rename to docs/explanation/scripts.md index e430726a3..dd1860edd 100644 --- a/doc/07.-Scripts-execution.md +++ b/docs/explanation/scripts.md @@ -9,7 +9,7 @@ Those scripts, can be triggered on: Scripts can be shell scripts, or any binary that can be executed on Linux. -![Scripts options in AD](images/Scripts-execution/gpo-scripts.png) +![Scripts options in AD](../images/explanation/scripts/gpo-scripts.png) ## Feature availability @@ -25,7 +25,7 @@ Scripts must be available in the assets sharing directory on your Active Directo In this directory, next to `Policies` in your domain folder, create a directory matching your distribution name. For instance `Ubuntu`, which will be the assets sharing directory. -![Assets folder in sysvol](images/Scripts-execution/assets-folder.png) +![Assets folder in sysvol](../images/explanation/scripts/assets-folder.png) It must also contain a `GPT.ini` file of the form: @@ -41,21 +41,21 @@ Then, place any scripts you need under the `scripts/` directory (subdirectories ## Automating the incrementation of the `GPT.ini` version stanza -Making manual changes to a file everytime scripts are changed can be unproductive and tedious. For your convenience, we developed a tool to automate this process. For detailed usage and installation instructions please refer to the [Active Directory Watch Daemon](14.-Active-Directory-Watch-Daemon.md) documentation. +Making manual changes to a file every time scripts are changed can be unproductive and tedious. For your convenience, we developed a tool to automate this process. For detailed usage and installation instructions please refer to the [Active Directory Watch Daemon](../reference/adwatchd.md) documentation. ## Active directory UI ### Enabled -The form is a list of scripts path, relative to the `scripts/` subdirectory of your assets sharing filesystem, one per line. +The form is a list of scripts path, relative to the `scripts/` subdirectory of your assets sharing file system, one per line. -![List of scripts example](images/Scripts-execution/scripts-list.png) +![List of scripts example](../images/explanation/scripts/scripts-list.png) ### Not configured or Disabled This GPO won’t refer any scripts for execution. -## Scripts behaviours +## Scripts behaviors ### Scripts erroring out diff --git a/doc/14.-Case-of-the-security-policy.md b/docs/explanation/security-policy.md similarity index 59% rename from doc/14.-Case-of-the-security-policy.md rename to docs/explanation/security-policy.md index f8a9d8c0c..a59aaaab7 100644 --- a/doc/14.-Case-of-the-security-policy.md +++ b/docs/explanation/security-policy.md @@ -1,13 +1,13 @@ # Case of the security policy -Some group policies are directly managed by **SSSD**. For those, **ADSys** is not involved at all. This is the case of the **Security Settings**. +Certain group policies are directly managed by **SSSD**. In such instances, **ADSys** is not involved at all. This is applicable to **Security Settings**. -In Windows Group Policy Management Editor, these keys are located in `[FOREST.ROOT] > Computer Configuration > Windows Settings > Security Settings` +In Windows Group Policy Management Editor,you can locate these keys at `[FOREST.ROOT] > Computer Configuration > Windows Settings > Security Settings` -The table below is a non-exhaustive list of Security Settings as defined in Windows and not managed by ADSys but still partially supported through SSSD. +Below is a table providing a non-comprehensive list of Security Settings defined in Windows, which are not managed by ADSys but receive partial support through SSSD. -| **Windows Setting** | -|---------------------| +| Windows Setting | +| --------------- | |**Account Policies > Password Policy**| |Enforce password history| |Maximum password age| @@ -18,7 +18,7 @@ The table below is a non-exhaustive list of Security Settings as defined in Wind |Account lockout duration| |Account lockout threshold| |Reset account lockout counter after| -|**Local Policies > User Rights Assignement**| +|**Local Policies > User Rights Assignment**| |Access this computer from the network| |Allow log on locally| |Allow log on through Remote Desktop Services| @@ -36,4 +36,4 @@ The table below is a non-exhaustive list of Security Settings as defined in Wind |Administrator account status| |Shutdown: Allow system to be shut down without having to log on| -You can get more information on SSSD [online](https://sssd.io/). +Get more information on [SSSD](https://sssd.io/). diff --git a/docs/how-to/index.md b/docs/how-to/index.md new file mode 100644 index 000000000..f6337e9b6 --- /dev/null +++ b/docs/how-to/index.md @@ -0,0 +1,34 @@ +# How-to guides + +These guides accompany you through the complete ADSys operations lifecycle. + +## Installation + +### Windows Domain Controller + +This is the configuration needed on Windows Domain Controller. + +```{toctree} +:titlesonly: +Set up AD +Set up adwatchd +``` + +### Linux client machine + +This section outlines how to join your client machine to the domain, install ADSys, and verify that the setup is correct. + +```{toctree} +:titlesonly: +Join machine to AD during installation +Join machine to AD manually +Set up ADSys +``` + +## Operations + +```{toctree} +:titlesonly: + +Use GPO with Ubuntu +``` diff --git a/docs/how-to/join-ad-installation.md b/docs/how-to/join-ad-installation.md new file mode 100644 index 000000000..b0ae617c4 --- /dev/null +++ b/docs/how-to/join-ad-installation.md @@ -0,0 +1,31 @@ +# How to join an Active Directory domain during installation + +In order to use Group Policies on an Ubuntu client, the first thing to do is, of course, to join the computer to an Active Directory domain. + +A machine can join an AD domain at installation time with the Ubuntu Desktop installer, or after installation, by manually setting up the connection to AD. + +## Join at installation time + +Joining during installation is only supported by the Ubuntu Desktop graphical installer Ubiquity. So, start an installation of Ubuntu Desktop as you would usually do and proceed to the page **"Who are you?"**. Enter user and computer name information. + +![Who are you installer screen](../images/how-to/join-machine-ad/installer-whoareyou.png) + +> *Note about the host name:* +> +> *In order to set and resolve the host name properly, you must enter the **Fully Qualified Domain Name** (FQDN) of the machine in the field "Your computer's name". For example, `host01.example.com` instead of only the host name `host01`.* +> +> *After installation you can check if it is correct with the command `hostname` and `hostname -f` which must return the name of the machine (`host01`) and the full name of the machine with the domain (`host01.example.com`) respectively.* + +Check the box **"Use Active Directory"** and click **"Continue"** to proceed with next step **"Configure Active Directory"**. + +On this page you can enter the address of the Active Directory controller and credentials of the user allowed to add machines to the domain. + +![Configure Active Directory installer screen](../images/how-to/join-machine-ad/installer-configure_ad.png) + +You can verify that the server is reachable by pressing **"Test Connection"**. + +Once all the information has been entered and is valid, press **"Continue"** to proceed with the remaining usual steps of the installation. + +At the end of the installation you can reboot the machine and you are ready to log in as a user of the domain on first boot. + +If anything goes wrong with the join process during installation, you will be notified by a dialog box. You can still reboot the machine, log in as the administrator user of the machine (i.e. the user you entered in the page **"Who are you?"**) and troubleshoot the issue. The [Ubuntu Server Guide](https://ubuntu.com/server/docs/service-sssd) provides instructions to perform such troubleshooting. diff --git a/docs/how-to/join-ad-manually.md b/docs/how-to/join-ad-manually.md new file mode 100644 index 000000000..3e990661d --- /dev/null +++ b/docs/how-to/join-ad-manually.md @@ -0,0 +1,31 @@ +# How to join an Active Directory domain manually + +ADSys supports two Active Directory backends: + +1. [SSSD](https://sssd.io/), or System Security Services Daemon, provides access to centralized identity management systems like Microsoft Active Directory, OpenLDAP, and various other directory servers. This client component retrieves and caches data from remote directory servers, delivering identity, authentication, and authorization services to the host machine. +2. [Winbind](https://wiki.samba.org/index.php/Configuring_Winbindd_on_a_Samba_AD_DC) is a component of the Samba suite that provides seamless integration and authentication services between UNIX or Linux systems and Windows-based networks, allowing the former to appear as members in a Windows Active Directory domain. + +## Join manually using SSSD + +The aim of this documentation is to describe how to operate ADSys. So we won’t do an in depth description of the operations to manually configure a connection to Active Directory from an Ubuntu Client. + +Authentication of Ubuntu against the Active Directory server requires to configure SSSD and Kerberos. SSSD will then retrieve the credentials and the initial security policy of the `Default Domain Policy`. + +All these operations are described in details in the [Ubuntu Server Guide “Service - SSSD”](https://ubuntu.com/server/docs/service-sssd) and the White Paper [How to integrate Ubuntu Desktop with Active Directory](https://ubuntu.com/engage/microsoft-active-directory). + +## Join manually using Winbind + +In addition to SSSD, ADSys supports Winbind as a backend. The easiest way to join a domain using Winbind is to use the `realmd` utility, as described in the [Samba - Active Directory](https://ubuntu.com/server/docs/samba-active-directory) guide. + +ADSys uses SSSD as a default backend, so Winbind has to be opted into explicitly via the following configuration option in `adsys.yaml`: + +```yaml +ad_backend: winbind +``` + +In addition, Winbind requires additional dependencies to be installed. On Ubuntu-based systems they can be installed by executing the following command, prior to ADSys: + +```sh +sudo apt update +sudo apt install winbind krb5-user +``` diff --git a/doc/03.-AD-Setup.md b/docs/how-to/set-up-ad.md similarity index 90% rename from doc/03.-AD-Setup.md rename to docs/how-to/set-up-ad.md index 3ae865f84..e130c246a 100644 --- a/doc/03.-AD-Setup.md +++ b/docs/how-to/set-up-ad.md @@ -1,4 +1,4 @@ -# Setting up the Active Directory Server +# How to set up the Active Directory Server Active Directory needs policy files (**.admx** and **.adml**) to know which settings can be changed on given clients and actions to be performed on users of the domain. @@ -21,7 +21,7 @@ Those are the 2 files that must be copied on your Active Directory server. You can find the latest version of those files in a [dedicated directory of the upstream repository](https://github.com/ubuntu/adsys/tree/main/policies). Note though that not all the keys may be supported by our local `ADSys` installation. Only the templates generated by `adysctl` match the version of your client. -The policy files are also shipped as part of the `adsys-windows` package, together with the [Active Directory Watch Daemon](14.-Active-Directory-Watch-Daemon.md). +The policy files are also shipped as part of the `adsys-windows` package, together with the [Active Directory Watch Daemon](../reference/adwatchd.md). ## Deployment of ADM files on the Active Directory server @@ -31,9 +31,9 @@ For more information read the Microsoft documentation ["create and manage the Ce Once loaded successfully in Active Directory, the Ubuntu specific settings are available in the **Group Policy Management Editor** under `[Policy Name] > Computer Configuration > Policies > Administrative Templates > Ubuntu` for the machine policies and `[Policy Name] > User Configuration > Policies > Administrative Templates > Ubuntu` for the user policies. -![Ubuntu GPOs in Active Directory](images/AD-Setup/gpo_editor-tree.png) +![Ubuntu GPOs in Active Directory](../images/how-to/set-up-ad/gpo_editor-tree.png) -![Ubuntu Settings details page](images/AD-Setup/gpo_editor-details.png) +![Ubuntu Settings details page](../images/how-to/set-up-ad/gpo_editor-details.png) ## Recommended readings diff --git a/docs/how-to/set-up-adsys.md b/docs/how-to/set-up-adsys.md new file mode 100644 index 000000000..8744dba97 --- /dev/null +++ b/docs/how-to/set-up-adsys.md @@ -0,0 +1,36 @@ +# How to set-up ADSys + +**ADSys** is not currently installed by default on Ubuntu desktop. This must be done manually by the local administrator of the machine. + +To do so, log in on first boot, update the repositories and install **ADSys**. On Ubuntu-based systems this can be accomplished with the following commands: + +```sh +sudo apt update +sudo apt install adsys +``` + +Reboot then to allow the machine to do its policy refresh. + +## Logging in as a user of the domain + +To log in as a user of the domain, press the link **"Not listed?"** in the greeter. Then enter the username followed by the password. + +### SSSD + +By default, there is no default domain configured in SSSD. You have to enter the full user name with one of the forms: `USER@DOMAIN.COM`, `USER@DOMAIN` or `DOMAIN/USER`. + +On the first log in the user's home directory is created. + +All of this (default domain, default path for home directories, default shell, etc.) is configurable in `/etc/sssd/sssd.conf`. + +### Winbind + +If Winbind is used as a backend, the account can be specified in one of the following forms: `USER@DOMAIN.COM`, `USER@DOMAIN` or `DOMAIN\\USER`. + +For the home directory to be created automatically on login, the `pam_mkhomedir` module can be enabled: + +```sh +sudo pam-auth-update --enable mkhomedir +``` + +Options such as the home directory path template, shell and others can be tweaked in `/etc/samba/smb.conf` and are documented in the [`smb.conf(5)`](https://www.samba.org/samba/docs/current/man-html/smb.conf.5.html) man page. diff --git a/doc/15.-Active-Directory-Watch-Daemon.md b/docs/how-to/set-up-adwatchd.md similarity index 79% rename from doc/15.-Active-Directory-Watch-Daemon.md rename to docs/how-to/set-up-adwatchd.md index 78eaf2655..0f1969a6b 100644 --- a/doc/15.-Active-Directory-Watch-Daemon.md +++ b/docs/how-to/set-up-adwatchd.md @@ -3,6 +3,7 @@ The **Active Directory Watch Daemon** (or `adwatchd`) is a Windows application geared towards automating the manual process of incrementing the version stanza of a `GPT.ini` file. At its core, the program can be simplified to the following steps: + - watch a list of user-configured directories for changes -- subdirectories are also watched, but only the root directory will have a `GPT.ini` file - when a change is detected, attempt to locate a `GPT.ini` file at the root of the watched directory, or create one if absent - if a `GPT.ini` file is found, increment the version stanza of the file by 1, thus signaling clients that a new version of the assets (including scripts) are available to download during the next client refresh @@ -14,6 +15,7 @@ The `adwatchd` executable is available as a standalone Windows executable file, ### Installing via the Ubuntu package To source the `adwatchd` executable from the `adsys-windows` Ubuntu package, we must run the following (on Ubuntu): + ```sh sudo apt install adsys-windows ``` @@ -29,6 +31,7 @@ Follow the installation steps, paying attention to the prompts, optionally speci ## Configuring and starting the daemon Regardless of how the application is installed, the configuration steps are the same: + - locate and run the `adwatchd.exe` executable to start the application's interactive configuration tool - specify a path for the configuration file, or leave it blank to use the default location (the directory where the executable is located) - specify a list of directories to watch, one per line (the program will block installation if any of the directories do not exist) @@ -36,26 +39,26 @@ Regardless of how the application is installed, the configuration steps are the - create the configuration file if it does not exist - install and start the `adwatchd` Windows service -For a better understanding on what directories should be configured for watching, please refer to the **Installing scripts on sysvol** section of the [Scripts execution](07.-Scripts-execution.md#Installing scripts on sysvol) document. +For a better understanding on what directories should be configured for watching, please refer to the **Installing scripts on sysvol** section of the [Scripts execution](../explanation/scripts#Installing scripts on sysvol) document. -Note that the interactive configuration tool can only be run if the `adwatchd` service is not already installed on the machine. Please refer to the [CLI usage](#cli-usage) section for instructions on how to granularly manage the service. +Note that the interactive configuration tool can only be run if the `adwatchd` service is not already installed on the machine. Please refer to the [CLI usage](#CLI usage) section for instructions on how to finely manage the service. We recommend making use of the interactive configuration tool to install the application, as it provides a level of error handling, taking care of path normalization and the creation of the configuration file. The configuration file is stored as a YAML file, and can be freely edited after the application has been installed. The following keys are configurable: ```yaml -verbose: 0 # 0 = warning, 1 = info, 2 = debug, 3 = debug with caller output +verbose: 0 # 0 = warning, 1 = info, 2 = debug, 3 = debug with caller output dirs: # list of directories to watch - C:\Windows\SYSVOL\sysvol\testdomain.com\Ubuntu # traditional path - \\testdomain.com\SYSVOL\testdomain.com\Ubuntu # UNC path ``` - + ### Configuring the service using a pre-filled configuration file For convenience, the `adwatchd` application can be configured with a pre-filled configuration file. Start a Command Prompt or PowerShell window and run one of the following: -```cmd +```bat REM Run the interactive configuration tool with a predefined configuration file REM REM This will start the interactive configuration tool with pre-filled entries for the @@ -89,23 +92,3 @@ The optional steps are only necessary if the intent is to do a complete upgrade 1. Run the installer, following the prompts The installer will automatically take care of the upgrade process, and will offer to stop the service if it is running prior to the upgrade, and start it afterwards. - -## Monitoring the application - -The service is configured to log to the Windows Event Log, and can be monitored using the [Event Viewer](https://docs.microsoft.com/en-us/shows/inside/event-viewer). By default, the application will only log events when it starts or stops, but the verbose level can be increased via the configuration file to log more information such as files being watched, or the `GPT.ini` file being updated. - -## CLI usage - -For more advanced usage, the application can be managed from the command line. If the application was installed via the bespoke installer, a helpful shortcut is available in the Start Menu: `Start Command Prompt with adwatchd`. This will start a Command Prompt window with the `adwatchd` executable in the `PATH`. - -The following commands are available: - -### `run` - -Starts the directory watch loop in foreground mode. This is useful for debugging purposes, as it can be called with the same arguments as the service. - -### `service` - -Provides a set of subcommands to manage the service. - -For detailed descriptions and configuration options of `adwatchd`, refer to the [Command line reference](16.-Command-line-reference.md) section. diff --git a/doc/04.-Using-GPO.md b/docs/how-to/use-gpo.md similarity index 85% rename from doc/04.-Using-GPO.md rename to docs/how-to/use-gpo.md index f332a07e8..df2ab948d 100644 --- a/doc/04.-Using-GPO.md +++ b/docs/how-to/use-gpo.md @@ -1,4 +1,4 @@ -# Using GPO with Ubuntu +# How to use GPO with Ubuntu As explained in previous chapter, there are 2 sets of Ubuntu specific settings in the **Group Policy Management Editor**: @@ -10,10 +10,10 @@ As explained in previous chapter, there are 2 sets of Ubuntu specific settings i For this example we will use a test domain called `warthogs.biz` with 2 separate OUs. * The machine is called `adclient04` and belongs to `warthogs.biz > MainOffice` -![Main Office OU in Active Directory](images/Using-GPO/gpo_ou_computer.png) +![Main Office OU in Active Directory](../images/how-to/use-gpo/gpo_ou_computer.png) * The user is called `bob` and belongs to `warthogs.biz > IT Dept > RnD` -![IT Deps/RnD OU in Active Directory](images/Using-GPO/gpo_ou_user.png) +![IT Deps/RnD OU in Active Directory](../images/how-to/use-gpo/gpo_ou_user.png) In this example, we will demonstrate how to change dconf settings. We will first modify the greeter background image to illustrate how to enforce a computer setting and the list of preferred applications in the launcher for the user settings. @@ -26,11 +26,11 @@ Launch the GPO Management editor and create a GPO in `warthogs.biz > MainOffice` 1. Enter a valid absolute path to a `.png` image on the client machine, e.g. `/usr/share/backgrounds/ubuntu-default-greyscale-wallpaper.png`. 1. Refresh the GPO rule on the client by rebooting the machine or running `adsysctl update -m` (You may be prompted to enter your password to check if have enough privileges to run the command) -![GDM Picture URI setting](images/Using-GPO/gpo_setting_enabled.png) +![GDM Picture URI setting](../images/how-to/use-gpo/gpo_setting_enabled.png) The change is now visible on the greeter. -![Greeter with custom background](images/Using-GPO/gpo_gdm_background.png) +![Greeter with custom background](../images/how-to/use-gpo/gpo_gdm_background.png) > Files are not copied by the Active Directory client and must already exist on the target system at this given path. @@ -40,19 +40,19 @@ The change is now visible on the greeter. 1. Select the list of favorite desktop applications setting in `User Configuration > Policies > Administrative Templates > Ubuntu > Desktop > Shell > List of desktop file IDs for favorite applications`. 1. Enter a list of valid .desktop file IDs, one per line, like the following: -```raw +``` libreoffice-writer.desktop snap-store_ubuntu-software.desktop yelp.desktop ``` -![Favorite applications settings](images/Using-GPO/gpo_setting_enabled_list_of_apps.png) +![Favorite applications settings](../images/how-to/use-gpo/gpo_setting_enabled_list_of_apps.png) 4. Refresh the GPO rule applied to the user by logging in or running `adsysctl update` as your current user or `adsysctl update --all` to refresh the computer and all active users. The list of applications showing up on the left side for your current Active Directory user should be updated. -![Customized list of applications](images/Using-GPO/gpo_setting_enabled_list_of_apps_applied.png) +![Customized list of applications](../images/how-to/use-gpo/gpo_setting_enabled_list_of_apps_applied.png) > There are other ways of defining a list in ADSys / Active Directory integration. Check the **“Different types of widgets”** section below. @@ -79,25 +79,25 @@ Next section will detail how to configure this and what happens when the Active Most GPO rules can have 3 states: `enabled`, `disabled`, `not configured`. These states may have different meanings depending on the manager. -![States](images/Using-GPO/gpo_setting_states.png) +![States](../images/how-to/use-gpo/gpo_setting_states.png) ### General information of a setting The **left pane** of the GPO Management Editor contains the options that can be edited when a setting is enabled. -![list of values for each release](images/Using-GPO/gpo_setting_left_pane.png) +![list of values for each release](../images/how-to/use-gpo/gpo_setting_left_pane.png) There is a default value for all the releases and an override for each supported release of Ubuntu. More about multiple releases in the next section. The **right pane** of the GPO Management editor contains the general information about the GPO including: * The description of the setting -* The type of settings (eg dconf) +* The type of settings (e.g. dconf) * The path of the key in our schema * The default value of the key that is used if nothing is set on the left pane. Note that if defaults differ between releases, this will be a list per release. * The list of releases that support this setting. -![General information of a setting](images/Using-GPO/gpo_setting_right_pane.png) +![General information of a setting](../images/how-to/use-gpo/gpo_setting_right_pane.png) ### Different types of widgets @@ -107,18 +107,18 @@ The type `Text` represents a single line of text. If you don’t enclose a strin The default value will be already set. -![Text field](images/Using-GPO/gpo_widget_text.png) +![Text field](../images/how-to/use-gpo/gpo_widget_text.png) #### Text list A multiline text field is used for this case. A list can be: -![Text list](images/Using-GPO/gpo_widget_multiline.png) +![Text list](../images/how-to/use-gpo/gpo_widget_multiline.png) * One item per line: any end of line will be considered as a delimiter Example: -```raw +``` libreoffice.desktop firefox.desktop nautilus.desktop @@ -126,7 +126,7 @@ nautilus.desktop * Multiple items on one line: a coma `,` is the item delimiter: -```raw +``` libreoffice.desktop, firefox.desktop, nautilus.desktop ``` @@ -134,7 +134,7 @@ libreoffice.desktop, firefox.desktop, nautilus.desktop * Both syntaxes can be combined: -```raw +``` libreoffice.desktop, firefox.desktop nautilus.desktop ``` @@ -143,7 +143,7 @@ The type can be either text or numeric: * Text list: -```raw +``` libreoffice.desktop firefox.desktop nautilus.desktop @@ -151,7 +151,7 @@ nautilus.desktop * Decimal list: -```raw +```none 42 300 10 @@ -165,7 +165,7 @@ Ensure that you enter the valid type of list, as expected by dconf setting. ADSy > >Text list: > ->```raw +>```none >'42' >'300' >'10' @@ -175,19 +175,19 @@ Ensure that you enter the valid type of list, as expected by dconf setting. ADSy A list field is a limited list of values to choose from. It is represented by a drop down list. -![Dropdown field](images/Using-GPO/gpo_widget_dropdown.png) +![Dropdown field](../images/how-to/use-gpo/gpo_widget_dropdown.png) #### Checkbox A checkbox will correspond to set to `true` or `false` values for the corresponding setting. The default value will be already selected. -![Checkbox field](images/Using-GPO/gpo_widget_checkbox.png) +![Checkbox field](../images/how-to/use-gpo/gpo_widget_checkbox.png) #### Decimal Decimal values are fields that allow only digits with optional upper and lower bounds. A spinner helps the user to increase or decrease the value. -![Checkbox field](images/Using-GPO/gpo_widget_decimal.png) +![Checkbox field](../images/how-to/use-gpo/gpo_widget_decimal.png) The limits, if any, will be specified in the right section, per release. @@ -203,6 +203,6 @@ By definition, override takes precedence over the default value defined at the t Finally, note that the help text on the right panel will list each default per release if they differ between themselves. In addition, it will list the supported releases for this setting. -![Different defaults between releases](images/Using-GPO/gpo_setting_multireleases.png) +![Different defaults between releases](../images/how-to/use-gpo/gpo_setting_multireleases.png) > Multi-release overrides are only available when your Active Directory administrative templates defines more than one release. If this is not the case, you will only see the top entry to define your policy. diff --git a/doc/images/Managing-AppArmor-profiles/apparmor-machine-ui.png b/docs/images/explanation/apparmor/apparmor-machine-ui.png similarity index 100% rename from doc/images/Managing-AppArmor-profiles/apparmor-machine-ui.png rename to docs/images/explanation/apparmor/apparmor-machine-ui.png diff --git a/doc/images/Managing-AppArmor-profiles/apparmor-user-ui.png b/docs/images/explanation/apparmor/apparmor-user-ui.png similarity index 100% rename from doc/images/Managing-AppArmor-profiles/apparmor-user-ui.png rename to docs/images/explanation/apparmor/apparmor-user-ui.png diff --git a/doc/images/Scripts-execution/assets-folder.png b/docs/images/explanation/apparmor/assets-folder.png similarity index 100% rename from doc/images/Scripts-execution/assets-folder.png rename to docs/images/explanation/apparmor/assets-folder.png diff --git a/doc/images/Certificate-auto-enrollment/advanced-configuration.png b/docs/images/explanation/certificates/advanced-configuration.png similarity index 100% rename from doc/images/Certificate-auto-enrollment/advanced-configuration.png rename to docs/images/explanation/certificates/advanced-configuration.png diff --git a/doc/images/Certificate-auto-enrollment/certificate-gpo.png b/docs/images/explanation/certificates/certificate-gpo.png similarity index 100% rename from doc/images/Certificate-auto-enrollment/certificate-gpo.png rename to docs/images/explanation/certificates/certificate-gpo.png diff --git a/doc/images/Certificate-auto-enrollment/certificate-settings.png b/docs/images/explanation/certificates/certificate-settings.png similarity index 100% rename from doc/images/Certificate-auto-enrollment/certificate-settings.png rename to docs/images/explanation/certificates/certificate-settings.png diff --git a/doc/images/Dconf/disabled.png b/docs/images/explanation/dconf/disabled.png similarity index 100% rename from doc/images/Dconf/disabled.png rename to docs/images/explanation/dconf/disabled.png diff --git a/doc/images/Dconf/enabled.png b/docs/images/explanation/dconf/enabled.png similarity index 100% rename from doc/images/Dconf/enabled.png rename to docs/images/explanation/dconf/enabled.png diff --git a/doc/images/Dconf/not_configured.png b/docs/images/explanation/dconf/not_configured.png similarity index 100% rename from doc/images/Dconf/not_configured.png rename to docs/images/explanation/dconf/not_configured.png diff --git a/doc/images/Network-shares/system-mounts-list.png b/docs/images/explanation/network-shares/system-mounts-list.png similarity index 100% rename from doc/images/Network-shares/system-mounts-list.png rename to docs/images/explanation/network-shares/system-mounts-list.png diff --git a/doc/images/Network-shares/system-mounts-policy-loc.png b/docs/images/explanation/network-shares/system-mounts-policy-loc.png similarity index 100% rename from doc/images/Network-shares/system-mounts-policy-loc.png rename to docs/images/explanation/network-shares/system-mounts-policy-loc.png diff --git a/doc/images/Network-shares/user-mounts-list.png b/docs/images/explanation/network-shares/user-mounts-list.png similarity index 100% rename from doc/images/Network-shares/user-mounts-list.png rename to docs/images/explanation/network-shares/user-mounts-list.png diff --git a/doc/images/Network-shares/user-mounts-policy-loc.png b/docs/images/explanation/network-shares/user-mounts-policy-loc.png similarity index 100% rename from doc/images/Network-shares/user-mounts-policy-loc.png rename to docs/images/explanation/network-shares/user-mounts-policy-loc.png diff --git a/doc/images/Privileges/privileges-options.png b/docs/images/explanation/privileges/privileges-options.png similarity index 100% rename from doc/images/Privileges/privileges-options.png rename to docs/images/explanation/privileges/privileges-options.png diff --git a/doc/images/Proxy-settings/system-proxy-settings-focus.png b/docs/images/explanation/proxy/system-proxy-settings-focus.png similarity index 100% rename from doc/images/Proxy-settings/system-proxy-settings-focus.png rename to docs/images/explanation/proxy/system-proxy-settings-focus.png diff --git a/doc/images/Proxy-settings/system-proxy-settings-list.png b/docs/images/explanation/proxy/system-proxy-settings-list.png similarity index 100% rename from doc/images/Proxy-settings/system-proxy-settings-list.png rename to docs/images/explanation/proxy/system-proxy-settings-list.png diff --git a/docs/images/explanation/scripts/assets-folder.png b/docs/images/explanation/scripts/assets-folder.png new file mode 100644 index 000000000..cf3444db8 Binary files /dev/null and b/docs/images/explanation/scripts/assets-folder.png differ diff --git a/doc/images/Scripts-execution/gpo-scripts.png b/docs/images/explanation/scripts/gpo-scripts.png similarity index 100% rename from doc/images/Scripts-execution/gpo-scripts.png rename to docs/images/explanation/scripts/gpo-scripts.png diff --git a/doc/images/Scripts-execution/scripts-list.png b/docs/images/explanation/scripts/scripts-list.png similarity index 100% rename from doc/images/Scripts-execution/scripts-list.png rename to docs/images/explanation/scripts/scripts-list.png diff --git a/doc/images/Prerequisites/installer-configure_ad.png b/docs/images/how-to/join-machine-ad/installer-configure_ad.png similarity index 100% rename from doc/images/Prerequisites/installer-configure_ad.png rename to docs/images/how-to/join-machine-ad/installer-configure_ad.png diff --git a/doc/images/Prerequisites/installer-whoareyou.png b/docs/images/how-to/join-machine-ad/installer-whoareyou.png similarity index 100% rename from doc/images/Prerequisites/installer-whoareyou.png rename to docs/images/how-to/join-machine-ad/installer-whoareyou.png diff --git a/doc/images/AD-Setup/gpo_editor-details.png b/docs/images/how-to/set-up-ad/gpo_editor-details.png similarity index 100% rename from doc/images/AD-Setup/gpo_editor-details.png rename to docs/images/how-to/set-up-ad/gpo_editor-details.png diff --git a/doc/images/AD-Setup/gpo_editor-tree.png b/docs/images/how-to/set-up-ad/gpo_editor-tree.png similarity index 100% rename from doc/images/AD-Setup/gpo_editor-tree.png rename to docs/images/how-to/set-up-ad/gpo_editor-tree.png diff --git a/doc/images/Using-GPO/gpo_gdm_background.png b/docs/images/how-to/use-gpo/gpo_gdm_background.png similarity index 100% rename from doc/images/Using-GPO/gpo_gdm_background.png rename to docs/images/how-to/use-gpo/gpo_gdm_background.png diff --git a/doc/images/Using-GPO/gpo_ou_computer.png b/docs/images/how-to/use-gpo/gpo_ou_computer.png similarity index 100% rename from doc/images/Using-GPO/gpo_ou_computer.png rename to docs/images/how-to/use-gpo/gpo_ou_computer.png diff --git a/doc/images/Using-GPO/gpo_ou_user.png b/docs/images/how-to/use-gpo/gpo_ou_user.png similarity index 100% rename from doc/images/Using-GPO/gpo_ou_user.png rename to docs/images/how-to/use-gpo/gpo_ou_user.png diff --git a/doc/images/Using-GPO/gpo_setting_enabled.png b/docs/images/how-to/use-gpo/gpo_setting_enabled.png similarity index 100% rename from doc/images/Using-GPO/gpo_setting_enabled.png rename to docs/images/how-to/use-gpo/gpo_setting_enabled.png diff --git a/doc/images/Using-GPO/gpo_setting_enabled_list_of_apps.png b/docs/images/how-to/use-gpo/gpo_setting_enabled_list_of_apps.png similarity index 100% rename from doc/images/Using-GPO/gpo_setting_enabled_list_of_apps.png rename to docs/images/how-to/use-gpo/gpo_setting_enabled_list_of_apps.png diff --git a/doc/images/Using-GPO/gpo_setting_enabled_list_of_apps_applied.png b/docs/images/how-to/use-gpo/gpo_setting_enabled_list_of_apps_applied.png similarity index 100% rename from doc/images/Using-GPO/gpo_setting_enabled_list_of_apps_applied.png rename to docs/images/how-to/use-gpo/gpo_setting_enabled_list_of_apps_applied.png diff --git a/doc/images/Using-GPO/gpo_setting_left_pane.png b/docs/images/how-to/use-gpo/gpo_setting_left_pane.png similarity index 100% rename from doc/images/Using-GPO/gpo_setting_left_pane.png rename to docs/images/how-to/use-gpo/gpo_setting_left_pane.png diff --git a/doc/images/Using-GPO/gpo_setting_multireleases.png b/docs/images/how-to/use-gpo/gpo_setting_multireleases.png similarity index 100% rename from doc/images/Using-GPO/gpo_setting_multireleases.png rename to docs/images/how-to/use-gpo/gpo_setting_multireleases.png diff --git a/doc/images/Using-GPO/gpo_setting_right_pane.png b/docs/images/how-to/use-gpo/gpo_setting_right_pane.png similarity index 100% rename from doc/images/Using-GPO/gpo_setting_right_pane.png rename to docs/images/how-to/use-gpo/gpo_setting_right_pane.png diff --git a/doc/images/Using-GPO/gpo_setting_states.png b/docs/images/how-to/use-gpo/gpo_setting_states.png similarity index 100% rename from doc/images/Using-GPO/gpo_setting_states.png rename to docs/images/how-to/use-gpo/gpo_setting_states.png diff --git a/doc/images/Using-GPO/gpo_widget_checkbox.png b/docs/images/how-to/use-gpo/gpo_widget_checkbox.png similarity index 100% rename from doc/images/Using-GPO/gpo_widget_checkbox.png rename to docs/images/how-to/use-gpo/gpo_widget_checkbox.png diff --git a/doc/images/Using-GPO/gpo_widget_decimal.png b/docs/images/how-to/use-gpo/gpo_widget_decimal.png similarity index 100% rename from doc/images/Using-GPO/gpo_widget_decimal.png rename to docs/images/how-to/use-gpo/gpo_widget_decimal.png diff --git a/doc/images/Using-GPO/gpo_widget_dropdown.png b/docs/images/how-to/use-gpo/gpo_widget_dropdown.png similarity index 100% rename from doc/images/Using-GPO/gpo_widget_dropdown.png rename to docs/images/how-to/use-gpo/gpo_widget_dropdown.png diff --git a/doc/images/Using-GPO/gpo_widget_multiline.png b/docs/images/how-to/use-gpo/gpo_widget_multiline.png similarity index 100% rename from doc/images/Using-GPO/gpo_widget_multiline.png rename to docs/images/how-to/use-gpo/gpo_widget_multiline.png diff --git a/doc/images/Using-GPO/gpo_widget_text.png b/docs/images/how-to/use-gpo/gpo_widget_text.png similarity index 100% rename from doc/images/Using-GPO/gpo_widget_text.png rename to docs/images/how-to/use-gpo/gpo_widget_text.png diff --git a/doc/images/The-adsys-daemon/daemon-polkit.png b/docs/images/reference/adsys-daemon/daemon-polkit.png similarity index 100% rename from doc/images/The-adsys-daemon/daemon-polkit.png rename to docs/images/reference/adsys-daemon/daemon-polkit.png diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 000000000..007c09628 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,61 @@ +# ADSys Documentation + +ADSys is the Active Directory Group Policy client for Ubuntu. + +ADSys enables system administrators to manage Ubuntu Desktop clients centrally via Microsoft Active Directory. It includes ADMX and ADML templates and allows policies to be applied at boot and login, then refreshed periodically. + +It simplifies the task of configuring Ubuntu systems in a Microsoft Active Directory environment. However, it doesn't handle user authentication or initial security policy, which are managed by SSSD/Winbind and PAM. + +ADSys is valuable for system administrators who wish to manage Ubuntu Desktop clients in a centralized manner through Microsoft Active Directory. + +```{toctree} +:hidden: +tutorial/index +how-to/index +reference/index +explanation/index +``` + +## In this documentation + +````{grid} 1 1 2 2 + +```{grid-item} +### [Tutorials](tutorial/index) + +**Start here**: a hands-on introduction to ADSys for new users +``` + +```{grid-item} +### [How-to guides](how-to/index) + +**Step-by-step guides** covering key operations and common tasks +``` + +```` + +````{grid} 1 1 2 2 + +```{grid-item} +### [Explanation](explanation/index) + +**Discussion and clarification** of key topics +``` + +```{grid-item} +### [Reference](reference/index) + +**Technical information** - specifications, APIs, architecture +``` + +```` + +## Project and community + +ADSys is a member of the Ubuntu family. It’s an open source project that warmly welcomes community contributions, suggestions, fixes and constructive feedback. + +* [Code of conduct](https://ubuntu.com/community/code-of-conduct) +* [Join us in the Ubuntu Community](https://discourse.ubuntu.com/c/desktop/8) +* [Contribute](https://github.com/ubuntu/adsys/blob/main/CONTRIBUTING.md) or [Report an issue](https://github.com/ubuntu/adsys/issues/new) +* [Thinking about using ADSys for your next project? Get in touch!](https://ubuntu.com/contact-us/form?product=generic-contact-us) +* [Licensed under GPL v3](https://github.com/ubuntu/adsys/blob/main/LICENSE) diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 000000000..32bb24529 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/doc/12.-The-adsys-daemon.md b/docs/reference/adsys-daemon.md similarity index 96% rename from doc/12.-The-adsys-daemon.md rename to docs/reference/adsys-daemon.md index cb2e4f746..3e27d7c86 100644 --- a/doc/12.-The-adsys-daemon.md +++ b/docs/reference/adsys-daemon.md @@ -112,7 +112,7 @@ run_dir: /tmp/adsysd/run # Backend selection: sssd (default) or winbind ad_backend: sssd -# SSSd configuration +# SSSD configuration sssd: config: /etc/sssd.conf cache_dir: /var/lib/sss/db @@ -133,7 +133,7 @@ client_timeout: 60 Increase the verbosity of the daemon or client. By default, only warnings and error logs are printed. This value is set between 0 and 3. This has the same effect as the `-v` and `-vv` flags. * **socket** -Path the unix socket for communication between clients and daemon. This can be overridden by the `--socket` option. Defaults to `/run/adsysd.sock` (monitored by systemd for socket activation). +Path the Unix socket for communication between clients and daemon. This can be overridden by the `--socket` option. Defaults to `/run/adsysd.sock` (monitored by systemd for socket activation). ### Service only configuration @@ -151,7 +151,7 @@ The run directory contains the links to the kerberos tickets for the machine and #### Backend specific options -##### SSSd +##### SSSD * **config** @@ -188,13 +188,13 @@ It is possible to follow the exchanges between all clients and the daemon with t Only privileged users have access to this information. As with any other command, the verbosity can be increased with `-v` flags (it’s independent of the daemon or client current verbosity). More flags increases the verbosity further up to 3. -More information is available in the [next chapter](./13.-The-adsysctl-command.md) covering adsysctl cat command. +More information is available in the [next chapter](adsysctl.md) covering adsysctl cat command. ## Authorizations **ADSys** uses a privilege mechanism based on polkit to manage authorizations. Many commands require elevated privileges to be executed. If the adsys client is executed with insufficient privileges to execute a command, the user will be prompted to enter its password. If allowed then the command will be executed and denied otherwise. -![Polkit authentication dialog](images/The-adsys-daemon/daemon-polkit.png) +![Polkit authentication dialog](../images/reference/adsys-daemon/daemon-polkit.png) This is configurable by the administrator as any service controlled by polkit. For more information `man polkit`. @@ -204,4 +204,4 @@ There are additional configuration options matching the adsysd command line opti ## Reference guide -Do not hesitate to use the shell completion and the `help` subcommands to get more informations about the subcommands. +Do not hesitate to use the shell completion and the `help` subcommands to get more information about the subcommands. diff --git a/docs/reference/adsysctl-cli.md b/docs/reference/adsysctl-cli.md new file mode 100644 index 000000000..4267696d0 --- /dev/null +++ b/docs/reference/adsysctl-cli.md @@ -0,0 +1,620 @@ +# adsysctl command line + +## User commands + +### adsysctl + +AD integration client + +#### Synopsis + +Active Directory integration bridging toolset command line tool. + +``` +adsysctl COMMAND [flags] +``` + +#### Options + +``` + -c, --config string use a specific configuration file + -h, --help help for adsysctl + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adsysctl applied + +Print last applied GPOs for current or given user/machine + +#### Synopsis + +Alias of "policy applied" + +``` +adsysctl applied [USER_NAME] [flags] +``` + +#### Options + +``` + -a, --all show overridden rules in each GPOs. + --details show applied rules in addition to GPOs. + -h, --help help for applied + -m, --machine show applied rules to the machine. + --no-color don't display colorized version. +``` + +#### Options inherited from parent commands + +``` + -c, --config string use a specific configuration file + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adsysctl completion + +Generate the autocompletion script for the specified shell + +#### Synopsis + +Generate the autocompletion script for adsysctl for the specified shell. +See each sub-command's help for details on how to use the generated script. + + +#### Options + +``` + -h, --help help for completion +``` + +#### Options inherited from parent commands + +``` + -c, --config string use a specific configuration file + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adsysctl completion bash + +Generate the autocompletion script for bash + +#### Synopsis + +Generate the autocompletion script for the bash shell. + +This script depends on the 'bash-completion' package. +If it is not installed already, you can install it via your OS's package manager. + +To load completions in your current shell session: + + source <(adsysctl completion bash) + +To load completions for every new session, execute once: + +##### Linux: + + adsysctl completion bash > /etc/bash_completion.d/adsysctl + +##### macOS: + + adsysctl completion bash > $(brew --prefix)/etc/bash_completion.d/adsysctl + +You will need to start a new shell for this setup to take effect. + + +``` +adsysctl completion bash +``` + +#### Options + +``` + -h, --help help for bash + --no-descriptions disable completion descriptions +``` + +#### Options inherited from parent commands + +``` + -c, --config string use a specific configuration file + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adsysctl completion fish + +Generate the autocompletion script for fish + +#### Synopsis + +Generate the autocompletion script for the fish shell. + +To load completions in your current shell session: + + adsysctl completion fish | source + +To load completions for every new session, execute once: + + adsysctl completion fish > ~/.config/fish/completions/adsysctl.fish + +You will need to start a new shell for this setup to take effect. + + +``` +adsysctl completion fish [flags] +``` + +#### Options + +``` + -h, --help help for fish + --no-descriptions disable completion descriptions +``` + +#### Options inherited from parent commands + +``` + -c, --config string use a specific configuration file + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adsysctl completion powershell + +Generate the autocompletion script for powershell + +#### Synopsis + +Generate the autocompletion script for powershell. + +To load completions in your current shell session: + + adsysctl completion powershell | Out-String | Invoke-Expression + +To load completions for every new session, add the output of the above command +to your powershell profile. + + +``` +adsysctl completion powershell [flags] +``` + +#### Options + +``` + -h, --help help for powershell + --no-descriptions disable completion descriptions +``` + +#### Options inherited from parent commands + +``` + -c, --config string use a specific configuration file + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adsysctl completion zsh + +Generate the autocompletion script for zsh + +#### Synopsis + +Generate the autocompletion script for the zsh shell. + +If shell completion is not already enabled in your environment you will need +to enable it. You can execute the following once: + + echo "autoload -U compinit; compinit" >> ~/.zshrc + +To load completions in your current shell session: + + source <(adsysctl completion zsh) + +To load completions for every new session, execute once: + +##### Linux: + + adsysctl completion zsh > "${fpath[1]}/_adsysctl" + +##### macOS: + + adsysctl completion zsh > $(brew --prefix)/share/zsh/site-functions/_adsysctl + +You will need to start a new shell for this setup to take effect. + + +``` +adsysctl completion zsh [flags] +``` + +#### Options + +``` + -h, --help help for zsh + --no-descriptions disable completion descriptions +``` + +#### Options inherited from parent commands + +``` + -c, --config string use a specific configuration file + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adsysctl doc + +Documentation + +``` +adsysctl doc [CHAPTER] [flags] +``` + +#### Options + +``` + -h, --help help for doc +``` + +#### Options inherited from parent commands + +``` + -c, --config string use a specific configuration file + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adsysctl policy + +Policy management + +``` +adsysctl policy COMMAND [flags] +``` + +#### Options + +``` + -h, --help help for policy +``` + +#### Options inherited from parent commands + +``` + -c, --config string use a specific configuration file + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adsysctl policy admx + +Dump windows policy definitions + +``` +adsysctl policy admx lts-only|all [flags] +``` + +#### Options + +``` + --distro string distro for which to retrieve policy definition. (default "Ubuntu") + -h, --help help for admx +``` + +#### Options inherited from parent commands + +``` + -c, --config string use a specific configuration file + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adsysctl policy applied + +Print last applied GPOs for current or given user/machine + +``` +adsysctl policy applied [USER_NAME] [flags] +``` + +#### Options + +``` + -a, --all show overridden rules in each GPOs. + --details show applied rules in addition to GPOs. + -h, --help help for applied + -m, --machine show applied rules to the machine. + --no-color don't display colorized version. +``` + +#### Options inherited from parent commands + +``` + -c, --config string use a specific configuration file + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adsysctl policy purge + +Purges policies for the current user or a specified one + +``` +adsysctl policy purge [USER_NAME] [flags] +``` + +#### Options + +``` + -a, --all all purges the policy of the computer and all the logged in users. -m or USER_NAME cannot be used with this option. + -h, --help help for purge + -m, --machine machine purges the policy of the computer. +``` + +#### Options inherited from parent commands + +``` + -c, --config string use a specific configuration file + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adsysctl policy update + +Updates/Create a policy for current user or given user with its kerberos ticket + +``` +adsysctl policy update [USER_NAME KERBEROS_TICKET_PATH] [flags] +``` + +#### Options + +``` + -a, --all all updates the policy of the computer and all the logged in users. -m or USER_NAME/TICKET cannot be used with this option. + -h, --help help for update + -m, --machine machine updates the policy of the computer. +``` + +#### Options inherited from parent commands + +``` + -c, --config string use a specific configuration file + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adsysctl service + +Service management + +``` +adsysctl service COMMAND [flags] +``` + +#### Options + +``` + -h, --help help for service +``` + +#### Options inherited from parent commands + +``` + -c, --config string use a specific configuration file + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adsysctl service cat + +Print service logs + +``` +adsysctl service cat [flags] +``` + +#### Options + +``` + -h, --help help for cat +``` + +#### Options inherited from parent commands + +``` + -c, --config string use a specific configuration file + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adsysctl service status + +Print service status + +``` +adsysctl service status [flags] +``` + +#### Options + +``` + -h, --help help for status +``` + +#### Options inherited from parent commands + +``` + -c, --config string use a specific configuration file + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adsysctl service stop + +Requests to stop the service once all connections are done + +``` +adsysctl service stop [flags] +``` + +#### Options + +``` + -f, --force force will shut it down immediately and drop existing connections. + -h, --help help for stop +``` + +#### Options inherited from parent commands + +``` + -c, --config string use a specific configuration file + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adsysctl update + +Updates/Create a policy for current user or given user with its kerberos ticket + +#### Synopsis + +Alias of "policy update" + +``` +adsysctl update [USER_NAME KERBEROS_TICKET_PATH] [flags] +``` + +#### Options + +``` + -a, --all all updates the policy of the computer and all the logged in users. -m or USER_NAME/TICKET cannot be used with this option. + -h, --help help for update + -m, --machine machine updates the policy of the computer. +``` + +#### Options inherited from parent commands + +``` + -c, --config string use a specific configuration file + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adsysctl version + +Returns version of client and service + +``` +adsysctl version [flags] +``` + +#### Options + +``` + -h, --help help for version +``` + +#### Options inherited from parent commands + +``` + -c, --config string use a specific configuration file + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +## Hidden commands + +Those commands are hidden from help and should primarily be used by the system or for debugging. + +### adsysctl policy debug + +Debug various policy infos + +``` +adsysctl policy debug [flags] +``` + +#### Options + +``` + -h, --help help for debug +``` + +#### Options inherited from parent commands + +``` + -c, --config string use a specific configuration file + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adsysctl policy debug cert-autoenroll-script + +Write certificate autoenrollment python embedded script in current directory + +``` +adsysctl policy debug cert-autoenroll-script [flags] +``` + +#### Options + +``` + -h, --help help for cert-autoenroll-script +``` + +#### Options inherited from parent commands + +``` + -c, --config string use a specific configuration file + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adsysctl policy debug gpolist-script + +Write GPO list python embedded script in current directory + +``` +adsysctl policy debug gpolist-script [flags] +``` + +#### Options + +``` + -h, --help help for gpolist-script +``` + +#### Options inherited from parent commands + +``` + -c, --config string use a specific configuration file + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + -t, --timeout int time in seconds before cancelling the client request when the server gives no result. 0 for no timeout. (default 30) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + diff --git a/doc/13.-The-adsysctl-command.md b/docs/reference/adsysctl.md similarity index 98% rename from doc/13.-The-adsysctl-command.md rename to docs/reference/adsysctl.md index 5a4e27799..7d935257e 100644 --- a/doc/13.-The-adsysctl-command.md +++ b/docs/reference/adsysctl.md @@ -186,7 +186,7 @@ You can get the list of connected users, when they were last refreshed, when the ## Debugging -The `cat` command has already been described in [the previous chapter](./12.-The-adsys-daemon.md). You can display logs with debugging levels independent of daemon and clients debugging levels. Local printing will also be forwarded. +The `cat` command has already been described in [the previous chapter](adsys-daemon.md). You can display logs with debugging levels independent of daemon and clients debugging levels. Local printing will also be forwarded. For example, running `cat` while the command `version` and `applied` are executed: @@ -228,7 +228,7 @@ adsysd 0.5 ### Documentation -An offline version of this documentation is available in the deamon. It will render the documentation on the command line. +An offline version of this documentation is available in the daemon. It will render the documentation on the command line. You can get a list of all chapters with their titles: @@ -257,7 +257,7 @@ Finally, there are different rendering modes to dump documentation in html for i ### Admx generation -The `policy admx` commands dumps pre-built Active Directory administrative templates that can be deployed on the Active Directory server. For more information, check the [AD setup documentation](./03.-AD-Setup.md) +The `policy admx` commands dumps pre-built Active Directory administrative templates that can be deployed on the Active Directory server. For more information, check the [AD setup documentation](../how-to/set-up-ad.md) ### Stopping the service diff --git a/docs/reference/adsysd-cli.md b/docs/reference/adsysd-cli.md new file mode 100644 index 000000000..7d9efecdf --- /dev/null +++ b/docs/reference/adsysd-cli.md @@ -0,0 +1,343 @@ +# adsysd command line + +## User commands + +### adsysd + +AD integration daemon + +#### Synopsis + +Active Directory integration bridging toolset daemon. + +``` +adsysd COMMAND [flags] +``` + +#### Options + +``` + --ad-backend string Active Directory authentication backend (default "sssd") + --cache-dir string directory where ADSys caches GPOs downloads and policies. (default "/var/cache/adsys") + -c, --config string use a specific configuration file + -h, --help help for adsysd + --run-dir string directory where ADSys stores transient information erased on reboot. (default "/run/adsys") + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + --sssd.cache-dir string SSSd cache directory (default "/var/lib/sss/db") + --sssd.config string SSSd config file path (default "/etc/sssd/sssd.conf") + -t, --timeout int time in seconds without activity before the service exists. 0 for no timeout. (default 120) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adsysd completion + +Generate the autocompletion script for the specified shell + +#### Synopsis + +Generate the autocompletion script for adsysd for the specified shell. +See each sub-command's help for details on how to use the generated script. + + +#### Options + +``` + -h, --help help for completion +``` + +#### Options inherited from parent commands + +``` + --ad-backend string Active Directory authentication backend (default "sssd") + --cache-dir string directory where ADSys caches GPOs downloads and policies. (default "/var/cache/adsys") + -c, --config string use a specific configuration file + --run-dir string directory where ADSys stores transient information erased on reboot. (default "/run/adsys") + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + --sssd.cache-dir string SSSd cache directory (default "/var/lib/sss/db") + --sssd.config string SSSd config file path (default "/etc/sssd/sssd.conf") + -t, --timeout int time in seconds without activity before the service exists. 0 for no timeout. (default 120) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adsysd completion bash + +Generate the autocompletion script for bash + +#### Synopsis + +Generate the autocompletion script for the bash shell. + +This script depends on the 'bash-completion' package. +If it is not installed already, you can install it via your OS's package manager. + +To load completions in your current shell session: + + source <(adsysd completion bash) + +To load completions for every new session, execute once: + +##### Linux: + + adsysd completion bash > /etc/bash_completion.d/adsysd + +##### macOS: + + adsysd completion bash > $(brew --prefix)/etc/bash_completion.d/adsysd + +You will need to start a new shell for this setup to take effect. + + +``` +adsysd completion bash +``` + +#### Options + +``` + -h, --help help for bash + --no-descriptions disable completion descriptions +``` + +#### Options inherited from parent commands + +``` + --ad-backend string Active Directory authentication backend (default "sssd") + --cache-dir string directory where ADSys caches GPOs downloads and policies. (default "/var/cache/adsys") + -c, --config string use a specific configuration file + --run-dir string directory where ADSys stores transient information erased on reboot. (default "/run/adsys") + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + --sssd.cache-dir string SSSd cache directory (default "/var/lib/sss/db") + --sssd.config string SSSd config file path (default "/etc/sssd/sssd.conf") + -t, --timeout int time in seconds without activity before the service exists. 0 for no timeout. (default 120) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adsysd completion fish + +Generate the autocompletion script for fish + +#### Synopsis + +Generate the autocompletion script for the fish shell. + +To load completions in your current shell session: + + adsysd completion fish | source + +To load completions for every new session, execute once: + + adsysd completion fish > ~/.config/fish/completions/adsysd.fish + +You will need to start a new shell for this setup to take effect. + + +``` +adsysd completion fish [flags] +``` + +#### Options + +``` + -h, --help help for fish + --no-descriptions disable completion descriptions +``` + +#### Options inherited from parent commands + +``` + --ad-backend string Active Directory authentication backend (default "sssd") + --cache-dir string directory where ADSys caches GPOs downloads and policies. (default "/var/cache/adsys") + -c, --config string use a specific configuration file + --run-dir string directory where ADSys stores transient information erased on reboot. (default "/run/adsys") + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + --sssd.cache-dir string SSSd cache directory (default "/var/lib/sss/db") + --sssd.config string SSSd config file path (default "/etc/sssd/sssd.conf") + -t, --timeout int time in seconds without activity before the service exists. 0 for no timeout. (default 120) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adsysd completion powershell + +Generate the autocompletion script for powershell + +#### Synopsis + +Generate the autocompletion script for powershell. + +To load completions in your current shell session: + + adsysd completion powershell | Out-String | Invoke-Expression + +To load completions for every new session, add the output of the above command +to your powershell profile. + + +``` +adsysd completion powershell [flags] +``` + +#### Options + +``` + -h, --help help for powershell + --no-descriptions disable completion descriptions +``` + +#### Options inherited from parent commands + +``` + --ad-backend string Active Directory authentication backend (default "sssd") + --cache-dir string directory where ADSys caches GPOs downloads and policies. (default "/var/cache/adsys") + -c, --config string use a specific configuration file + --run-dir string directory where ADSys stores transient information erased on reboot. (default "/run/adsys") + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + --sssd.cache-dir string SSSd cache directory (default "/var/lib/sss/db") + --sssd.config string SSSd config file path (default "/etc/sssd/sssd.conf") + -t, --timeout int time in seconds without activity before the service exists. 0 for no timeout. (default 120) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adsysd completion zsh + +Generate the autocompletion script for zsh + +#### Synopsis + +Generate the autocompletion script for the zsh shell. + +If shell completion is not already enabled in your environment you will need +to enable it. You can execute the following once: + + echo "autoload -U compinit; compinit" >> ~/.zshrc + +To load completions in your current shell session: + + source <(adsysd completion zsh) + +To load completions for every new session, execute once: + +##### Linux: + + adsysd completion zsh > "${fpath[1]}/_adsysd" + +##### macOS: + + adsysd completion zsh > $(brew --prefix)/share/zsh/site-functions/_adsysd + +You will need to start a new shell for this setup to take effect. + + +``` +adsysd completion zsh [flags] +``` + +#### Options + +``` + -h, --help help for zsh + --no-descriptions disable completion descriptions +``` + +#### Options inherited from parent commands + +``` + --ad-backend string Active Directory authentication backend (default "sssd") + --cache-dir string directory where ADSys caches GPOs downloads and policies. (default "/var/cache/adsys") + -c, --config string use a specific configuration file + --run-dir string directory where ADSys stores transient information erased on reboot. (default "/run/adsys") + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + --sssd.cache-dir string SSSd cache directory (default "/var/lib/sss/db") + --sssd.config string SSSd config file path (default "/etc/sssd/sssd.conf") + -t, --timeout int time in seconds without activity before the service exists. 0 for no timeout. (default 120) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adsysd version + +Returns version of service and exits + +``` +adsysd version [flags] +``` + +#### Options + +``` + -h, --help help for version +``` + +#### Options inherited from parent commands + +``` + --ad-backend string Active Directory authentication backend (default "sssd") + --cache-dir string directory where ADSys caches GPOs downloads and policies. (default "/var/cache/adsys") + -c, --config string use a specific configuration file + --run-dir string directory where ADSys stores transient information erased on reboot. (default "/run/adsys") + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + --sssd.cache-dir string SSSd cache directory (default "/var/lib/sss/db") + --sssd.config string SSSd config file path (default "/etc/sssd/sssd.conf") + -t, --timeout int time in seconds without activity before the service exists. 0 for no timeout. (default 120) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +## Hidden commands + +Those commands are hidden from help and should primarily be used by the system or for debugging. + +### adsysd mount + +Mount the locations listed in the specified file for the current user + +``` +adsysd mount MOUNTS_FILE [flags] +``` + +#### Options + +``` + -h, --help help for mount +``` + +#### Options inherited from parent commands + +``` + --ad-backend string Active Directory authentication backend (default "sssd") + --cache-dir string directory where ADSys caches GPOs downloads and policies. (default "/var/cache/adsys") + -c, --config string use a specific configuration file + --run-dir string directory where ADSys stores transient information erased on reboot. (default "/run/adsys") + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + --sssd.cache-dir string SSSd cache directory (default "/var/lib/sss/db") + --sssd.config string SSSd config file path (default "/etc/sssd/sssd.conf") + -t, --timeout int time in seconds without activity before the service exists. 0 for no timeout. (default 120) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adsysd runscripts + +Runs scripts in the given subdirectory + +``` +adsysd runscripts ORDER_FILE [flags] +``` + +#### Options + +``` + --allow-order-missing allow ORDER_FILE to be missing once the scripts are ready. + -h, --help help for runscripts +``` + +#### Options inherited from parent commands + +``` + --ad-backend string Active Directory authentication backend (default "sssd") + --cache-dir string directory where ADSys caches GPOs downloads and policies. (default "/var/cache/adsys") + -c, --config string use a specific configuration file + --run-dir string directory where ADSys stores transient information erased on reboot. (default "/run/adsys") + -s, --socket string socket path to use between daemon and client. Can be overridden by systemd socket activation. (default "/run/adsysd.sock") + --sssd.cache-dir string SSSd cache directory (default "/var/lib/sss/db") + --sssd.config string SSSd config file path (default "/etc/sssd/sssd.conf") + -t, --timeout int time in seconds without activity before the service exists. 0 for no timeout. (default 120) + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + diff --git a/docs/reference/adwatchd-cli.md b/docs/reference/adwatchd-cli.md new file mode 100644 index 000000000..d060689cb --- /dev/null +++ b/docs/reference/adwatchd-cli.md @@ -0,0 +1,434 @@ +# adwatchd command line + +## User commands + +### adwatchd + +AD watch daemon + +#### Synopsis + +Watch directories for changes and bump the relevant GPT.ini versions. + +``` +adwatchd [COMMAND] [flags] +``` + +#### Options + +``` + -c, --config string use a specific configuration file + -h, --help help for adwatchd + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adwatchd completion + +Generate the autocompletion script for the specified shell + +#### Synopsis + +Generate the autocompletion script for adwatchd for the specified shell. +See each sub-command's help for details on how to use the generated script. + + +#### Options + +``` + -h, --help help for completion +``` + +#### Options inherited from parent commands + +``` + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adwatchd completion bash + +Generate the autocompletion script for bash + +#### Synopsis + +Generate the autocompletion script for the bash shell. + +This script depends on the 'bash-completion' package. +If it is not installed already, you can install it via your OS's package manager. + +To load completions in your current shell session: + + source <(adwatchd completion bash) + +To load completions for every new session, execute once: + +##### Linux: + + adwatchd completion bash > /etc/bash_completion.d/adwatchd + +##### macOS: + + adwatchd completion bash > $(brew --prefix)/etc/bash_completion.d/adwatchd + +You will need to start a new shell for this setup to take effect. + + +``` +adwatchd completion bash +``` + +#### Options + +``` + -h, --help help for bash + --no-descriptions disable completion descriptions +``` + +#### Options inherited from parent commands + +``` + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adwatchd completion fish + +Generate the autocompletion script for fish + +#### Synopsis + +Generate the autocompletion script for the fish shell. + +To load completions in your current shell session: + + adwatchd completion fish | source + +To load completions for every new session, execute once: + + adwatchd completion fish > ~/.config/fish/completions/adwatchd.fish + +You will need to start a new shell for this setup to take effect. + + +``` +adwatchd completion fish [flags] +``` + +#### Options + +``` + -h, --help help for fish + --no-descriptions disable completion descriptions +``` + +#### Options inherited from parent commands + +``` + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adwatchd completion powershell + +Generate the autocompletion script for powershell + +#### Synopsis + +Generate the autocompletion script for powershell. + +To load completions in your current shell session: + + adwatchd completion powershell | Out-String | Invoke-Expression + +To load completions for every new session, add the output of the above command +to your powershell profile. + + +``` +adwatchd completion powershell [flags] +``` + +#### Options + +``` + -h, --help help for powershell + --no-descriptions disable completion descriptions +``` + +#### Options inherited from parent commands + +``` + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adwatchd completion zsh + +Generate the autocompletion script for zsh + +#### Synopsis + +Generate the autocompletion script for the zsh shell. + +If shell completion is not already enabled in your environment you will need +to enable it. You can execute the following once: + + echo "autoload -U compinit; compinit" >> ~/.zshrc + +To load completions in your current shell session: + + source <(adwatchd completion zsh) + +To load completions for every new session, execute once: + +##### Linux: + + adwatchd completion zsh > "${fpath[1]}/_adwatchd" + +##### macOS: + + adwatchd completion zsh > $(brew --prefix)/share/zsh/site-functions/_adwatchd + +You will need to start a new shell for this setup to take effect. + + +``` +adwatchd completion zsh [flags] +``` + +#### Options + +``` + -h, --help help for zsh + --no-descriptions disable completion descriptions +``` + +#### Options inherited from parent commands + +``` + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adwatchd run + +Starts the directory watch loop + +#### Synopsis + +Can run as a service through the service manager or interactively as a standalone application. + +The program will monitor the configured directories for changes and bump the appropriate GPT.ini versions anytime a change is detected. +If a GPT.ini file does not exist for a directory, a warning will be issued and the file will be created. If the GPT.ini file is incompatible or malformed, the program will report an error. + + +``` +adwatchd run [flags] +``` + +#### Options + +``` + -c, --config string use a specific configuration file + -d, --dirs directory a directory to check for changes (can be specified multiple times) + -f, --force force the program to run even if another instance is already running + -h, --help help for run +``` + +#### Options inherited from parent commands + +``` + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adwatchd service + +Manages the adwatchd service + +#### Synopsis + +The service command allows the user to interact with the adwatchd service. It can manage and query the service status, and also install and uninstall the service. + +``` +adwatchd service COMMAND [flags] +``` + +#### Options + +``` + -h, --help help for service +``` + +#### Options inherited from parent commands + +``` + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adwatchd service install + +Installs the service + +#### Synopsis + +Installs the adwatchd service. + +The service will be installed as a Windows service. + + +``` +adwatchd service install [flags] +``` + +#### Options + +``` + -c, --config string use a specific configuration file + -h, --help help for install +``` + +#### Options inherited from parent commands + +``` + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adwatchd service restart + +Restarts the service + +#### Synopsis + +Restarts the adwatchd service. + +``` +adwatchd service restart [flags] +``` + +#### Options + +``` + -h, --help help for restart +``` + +#### Options inherited from parent commands + +``` + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adwatchd service start + +Starts the service + +#### Synopsis + +Starts the adwatchd service. + +``` +adwatchd service start [flags] +``` + +#### Options + +``` + -h, --help help for start +``` + +#### Options inherited from parent commands + +``` + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adwatchd service status + +Returns service status + +#### Synopsis + +Returns the status of the adwatchd service. + +``` +adwatchd service status [flags] +``` + +#### Options + +``` + -h, --help help for status +``` + +#### Options inherited from parent commands + +``` + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adwatchd service stop + +Stops the service + +#### Synopsis + +Stops the adwatchd service. + +``` +adwatchd service stop [flags] +``` + +#### Options + +``` + -h, --help help for stop +``` + +#### Options inherited from parent commands + +``` + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adwatchd service uninstall + +Uninstalls the service + +#### Synopsis + +Uninstalls the adwatchd service. + +``` +adwatchd service uninstall [flags] +``` + +#### Options + +``` + -h, --help help for uninstall +``` + +#### Options inherited from parent commands + +``` + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +### adwatchd version + +Returns version of service and exits + +``` +adwatchd version [flags] +``` + +#### Options + +``` + -h, --help help for version +``` + +#### Options inherited from parent commands + +``` + -v, --verbose count issue INFO (-v), DEBUG (-vv) or DEBUG with caller (-vvv) output +``` + +## Hidden commands + +Those commands are hidden from help and should primarily be used by the system or for debugging. + diff --git a/docs/reference/adwatchd.md b/docs/reference/adwatchd.md new file mode 100644 index 000000000..7fc7dd6ba --- /dev/null +++ b/docs/reference/adwatchd.md @@ -0,0 +1,16 @@ +# Active Directory Watch Daemon + +## Monitoring the application + +`adwatchd` is configured to log to the Windows Event Log, and can be monitored using the [Event Viewer](https://docs.microsoft.com/en-us/shows/inside/event-viewer). By default, the application will only log events when it starts or stops, but the verbose level can be increased via the configuration file to log more information such as files being watched, or the `GPT.ini` file being updated. + +## CLI usage + +For more advanced usage, the application can be managed from the command line. If the application was installed via the bespoke installer, a helpful shortcut is available in the Start Menu: `Start Command Prompt with adwatchd`. This will start a Command Prompt window with the `adwatchd` executable in the `PATH`. + +There are two commands available: + +* The `run` command starts the directory watch loop in foreground mode. This is useful for debugging purposes, as it can be called with the same arguments as the service. +* The `service` provides a set of subcommands to manage the service. + +For detailed descriptions and configuration options of `adwatchd`, refer to the [Command line reference](adwatchd-cli.md) section. diff --git a/docs/reference/index.md b/docs/reference/index.md new file mode 100644 index 000000000..96069b536 --- /dev/null +++ b/docs/reference/index.md @@ -0,0 +1,44 @@ +# Technical Reference + +This section consolidates technical details on ADSys, including specifications, APIs, and architecture. + +On the Linux side, ADSys is composed of a daemon and a command line interface: + +* The daemon - `adsysd` - implements the Group Policy protocol. It relies on Kerberos, Samba and LDAP for authentication and policy retrieval. +* The command line interface - `adsysctl` - controls the daemon and reports its status. + +A Windows daemon, `adwatchd` can be installed on the domain controller to automatically refresh assets without system administrator interventions. + +````{grid} 1 1 2 2 +```{grid-item} +## Reference + +```{toctree} +:titlesonly: +ADSys Control (adsysctl) +ADSys Daemon (adsysd) +ADSys Watch Daemon (adwatchd) +``` + +```{grid-item} +## Command line + +```{toctree} +:titlesonly: +adsysctl +adsysd +adwatchd +``` + +```` + +## Supported releases + +**ADSys** is supported on Ubuntu starting from **20.04.2 LTS**, and tested with Windows Server 2019. + +Only Active Directory on-premise is supported. + +## Recommended readings + +* `adsysd help` or `man adsysd`. +* `adsysctl help` or `man adsysctl`. diff --git a/docs/reuse/doc-cheat-sheet-myst.md.syntax b/docs/reuse/doc-cheat-sheet-myst.md.syntax new file mode 100644 index 000000000..19b07f531 --- /dev/null +++ b/docs/reuse/doc-cheat-sheet-myst.md.syntax @@ -0,0 +1,243 @@ +--- +orphan: true +myst: + substitutions: + reuse_key: "This is **included** text." + advanced_reuse_key: "This is a substitution that includes a code block: + ``` + code block + ```" +--- + +(cheat-sheet-myst)= +# Markdown/MyST cheat sheet + +This file contains the syntax for commonly used Markdown and MyST markup. +Open it in your text editor to quickly copy and paste the markup you need. + +Also see the [MyST documentation](https://myst-parser.readthedocs.io/en/latest/index.html) for detailed information, and the [Canonical Documentation Style Guide](https://docs.ubuntu.com/styleguide/en) for general style conventions. + +## H2 heading + +### H3 heading + +#### H4 heading + +##### H5 heading + +## Inline formatting + +- {guilabel}`UI element` +- `code` +- {command}`command` +- {kbd}`Key` +- *Italic* +- **Bold** + +## Code blocks + +Start a code block: + + code: + - example: true + +``` +# Demonstrate a code block +code: + - example: true +``` + +```yaml +# Demonstrate a code block +code: + - example: true +``` + +(_a_section_target)= +## Links + +- [Canonical website](https://canonical.com/) +- https://canonical.com/ +- {ref}`a_section_target` +- {ref}`Link text ` +- {doc}`index` +- {doc}`Link text ` + + +## Navigation + +Use the following syntax:: + + ```{toctree} + :hidden: + + sub-page1 + sub-page2 + ``` + +## Lists + +1. Step 1 + - Item 1 + * Sub-item + - Item 2 + 1. Sub-step 1 + 1. Sub-step 2 +1. Step 2 + 1. Sub-step 1 + - Item + 1. Sub-step 2 + +Term 1 +: Definition + +Term 2 +: Definition + +## Tables + +## Markdown tables + +| Header 1 | Header 2 | +|------------------------------------|----------| +| Cell 1
Second paragraph | Cell 2 | +| Cell 3 | Cell 4 | + +Centred: + +| Header 1 | Header 2 | +|:----------------------------------:|:--------:| +| Cell 1
Second paragraph | Cell 2 | +| Cell 3 | Cell 4 | + +## List tables + +```{list-table} + :header-rows: 1 + +* - Header 1 + - Header 2 +* - Cell 1 + + Second paragraph + - Cell 2 +* - Cell 3 + - Cell 4 +``` + +Centred: + +```{list-table} + :header-rows: 1 + :align: center + +* - Header 1 + - Header 2 +* - Cell 1 + + Second paragraph + - Cell 2 +* - Cell 3 + - Cell 4 +``` + +## Notes + +```{note} +A note. +``` + +```{tip} +A tip. +``` + +```{important} +Important information +``` + +```{caution} +This might damage your hardware! +``` + +## Images + +![Alt text](https://assets.ubuntu.com/v1/b3b72cb2-canonical-logo-166.png) + +```{figure} https://assets.ubuntu.com/v1/b3b72cb2-canonical-logo-166.png + :width: 100px + :alt: Alt text + + Figure caption +``` + +## Reuse + +### Keys + +Keys can be defined at the top of a file, or in a `myst_substitutions` option in `conf.py`. + +{{reuse_key}} + +{{advanced_reuse_key}} + +### File inclusion + +```{include} index.rst + :start-after: include_start + :end-before: include_end +``` + +## Tabs + +````{tabs} +```{group-tab} Tab 1 + +Content Tab 1 +``` + +```{group-tab} Tab 2 +Content Tab 2 +``` +```` + +## Glossary + +```{glossary} + +some term + Definition of the example term. +``` + +{term}`some term` + +## More useful markup + +- ```{versionadded} X.Y +- {abbr}`API (Application Programming Interface)` + +---- + +## Custom extensions + +Related links at the top of the page (surrounded by `---`): + + relatedlinks: https://github.com/canonical/lxd-sphinx-extensions, [RTFM](https://www.google.com) + discourse: 12345 + +Terms that should not be checked by the spelling checker: {spellexception}`PurposelyWrong` + +A terminal view with input and output: + +```{terminal} + :input: command + :user: root + :host: vampyr + +the output +``` + +A link to a YouTube video: + +```{youtube} https://www.youtube.com/watch?v=iMLiK1fX4I0 + :title: Demo +``` diff --git a/docs/reuse/links.txt b/docs/reuse/links.txt new file mode 100644 index 000000000..04cfff56e --- /dev/null +++ b/docs/reuse/links.txt @@ -0,0 +1,4 @@ +.. _reStructuredText style guide: https://canonical-documentation-with-sphinx-and-readthedocscom.readthedocs-hosted.com/style-guide/ +.. _Read the Docs at Canonical: https://library.canonical.com/documentation/read-the-docs +.. _How to publish documentation on Read the Docs: https://library.canonical.com/documentation/publish-on-read-the-docs +.. _Example product documentation: https://canonical-example-product-documentation.readthedocs-hosted.com/ diff --git a/docs/tutorial/index.md b/docs/tutorial/index.md new file mode 100644 index 000000000..de12634fa --- /dev/null +++ b/docs/tutorial/index.md @@ -0,0 +1,3 @@ +# Tutorials + +**Start here**: a hands-on introduction to ADSys for new users diff --git a/go.mod b/go.mod index 477a7aeba..5493d487a 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,6 @@ require ( github.com/fsnotify/fsnotify v1.7.0 github.com/godbus/dbus/v5 v5.1.0 github.com/golang/protobuf v1.5.3 - github.com/gomarkdown/markdown v0.0.0-20230922105210-14b16010c2ee github.com/google/uuid v1.3.1 github.com/kardianos/service v1.2.2 github.com/leonelquinteros/gotext v1.5.3-0.20230829162019-37f474cfb069 diff --git a/go.sum b/go.sum index f9656127c..2c4aaa9d3 100644 --- a/go.sum +++ b/go.sum @@ -119,8 +119,6 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/gomarkdown/markdown v0.0.0-20230922105210-14b16010c2ee h1:gvsnG+uIVkOue7HrYAG2ZnOdLoJTqsLyuBFJaU0kX4M= -github.com/gomarkdown/markdown v0.0.0-20230922105210-14b16010c2ee/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= diff --git a/internal/adsysservice/doc.go b/internal/adsysservice/doc.go index 5a4b3850f..c83f6a90d 100644 --- a/internal/adsysservice/doc.go +++ b/internal/adsysservice/doc.go @@ -4,20 +4,19 @@ import ( "bufio" "embed" "fmt" - "io" - "sort" + "path/filepath" + "regexp" "strings" "github.com/ubuntu/adsys" - "github.com/ubuntu/adsys/doc" + "github.com/ubuntu/adsys/docs" "github.com/ubuntu/adsys/internal/authorizer" log "github.com/ubuntu/adsys/internal/grpc/logstreamer" "github.com/ubuntu/adsys/internal/i18n" "github.com/ubuntu/decorate" ) -// GetDoc returns a chapter documentation from server -// If chapter is empty, all documentation documentation is outputted, with a separator between them. +// GetDoc returns a chapter documentation from server. func (s *Service) GetDoc(r *adsys.GetDocRequest, stream adsys.Service_GetDocServer) (err error) { defer decorate.OnError(&err, i18n.G("error while getting documentation")) @@ -25,50 +24,24 @@ func (s *Service) GetDoc(r *adsys.GetDocRequest, stream adsys.Service_GetDocServ return err } - onlineDocURL := doc.GetPackageURL() - - var out string - docDir := doc.Dir - // Get all documentation, separate file names with special characters - if chapter := r.GetChapter(); chapter == "" { - fs, err := docDir.ReadDir(".") - if err != nil { - return fmt.Errorf(i18n.G("could not list documentation directory: %v"), err) - } - // Sort all file names, having a chapter prefix - var names []string - for _, f := range fs { - names = append(names, f.Name()) - } - sort.Strings(names) + // Get all documentation metadata + _, chaptersToFiles, filesToTitle, err := docStructure(docs.Dir, "index.md", "") + if err != nil { + return fmt.Errorf(i18n.G("could not list documentation directory: %v"), err) + } - for _, n := range names { - d, err := docDir.ReadFile(n) - if err != nil { - return err - } - out = fmt.Sprintf("%s%s%s\n%s", out, doc.SplitFilesToken, strings.TrimSuffix(n, ".md"), string(d)) - } - } else { - // Get a give chapter content - filename, err := documentChapterToFileName(docDir, chapter) - if err != nil { - return err - } + // Find a match, removing trailing / for directory folder. + chapter := strings.TrimSuffix(strings.ToLower(r.GetChapter()), "/") - f, err := docDir.Open(filename) - if err != nil { - return fmt.Errorf(i18n.G("no chapter %q found in documentation"), chapter) - } - defer f.Close() + p, ok := chaptersToFiles[chapter] + if !ok { + return fmt.Errorf("no documentation found for %q", r.GetChapter()) + } - content, err := io.ReadAll(f) - if err != nil { - return fmt.Errorf(i18n.G("could not read chapter %q: %v"), chapter, err) - } - out = fmt.Sprintf("%s%s\n%s", doc.SplitFilesToken, strings.TrimSuffix(filename, ".md"), string(content)) + out, err := renderDocumentationPage(p, filesToTitle) + if err != nil { + return fmt.Errorf(i18n.G("could not read chapter %q: %v"), chapter, err) } - out = strings.ReplaceAll(out, "(images/", fmt.Sprintf("(%s/images/", onlineDocURL)) if err := stream.Send(&adsys.StringResponse{ Msg: out, @@ -79,90 +52,244 @@ func (s *Service) GetDoc(r *adsys.GetDocRequest, stream adsys.Service_GetDocServ } // ListDoc returns a list of all documentation from server. -func (s *Service) ListDoc(r *adsys.ListDocRequest, stream adsys.Service_ListDocServer) (err error) { +func (s *Service) ListDoc(_ *adsys.Empty, stream adsys.Service_ListDocServer) (err error) { defer decorate.OnError(&err, i18n.G("error while listing documentation")) if err := s.authorizer.IsAllowedFromContext(stream.Context(), authorizer.ActionAlwaysAllowed); err != nil { return err } - fs, err := doc.Dir.ReadDir(".") + chapters, _, _, err := docStructure(docs.Dir, "index.md", "") if err != nil { return fmt.Errorf(i18n.G("could not list documentation directory: %v"), err) } - // Sort all file names while they have their prefix - var names []string - for _, f := range fs { - names = append(names, f.Name()) + if err := stream.Send(&adsys.ListDocReponse{ + Chapters: chapters, + }); err != nil { + log.Warningf(stream.Context(), "couldn't send documentation to client: %v", err) } - sort.Strings(names) + return nil +} - var content string - if !r.GetRaw() { - content += "# Table of content\n" +// docStructure parses the toc and order documentation based on subsections toc appearance. +// It returns a list of ordered chapters names for completion, a map from chapter name + alias to filename +// and filename to their title name. +// We assume toc trees are only in index files. +func docStructure(dir embed.FS, indexFilePath, parentChapterName string) (orderedChapters []string, chaptersToFiles map[string]string, filesToTitle map[string]string, err error) { + chaptersToFiles, filesToTitle = make(map[string]string), make(map[string]string) + + f, err := dir.Open(indexFilePath) + if err != nil { + return nil, nil, nil, fmt.Errorf("could not get main index file: %w", err) } - for _, n := range names { - if r.GetRaw() { - content += fmt.Sprintln(fileNameToDocumentChapter(n)) + defer f.Close() + + startToctree := "```{toctree}" + endToctree := "```" + + root := filepath.Dir(indexFilePath) + + var inTocTree bool + s := bufio.NewScanner(f) + for s.Scan() { + t := strings.TrimSpace(s.Text()) + if t == startToctree { + inTocTree = true + continue + } else if t == endToctree { + inTocTree = false + } + + // Add the original index + if strings.HasPrefix(t, "# ") && indexFilePath == "index.md" { + chaptersToFiles[""] = indexFilePath + title := strings.TrimPrefix(t, "# ") + filesToTitle[indexFilePath] = title + chapterName := toCmdlineChapterName(title, "") + chaptersToFiles[chapterName] = indexFilePath + orderedChapters = append(orderedChapters, chapterName) + } + + if !inTocTree { + continue + } + + if strings.HasPrefix(t, ":") || t == "" { continue } - title := i18n.G("- can't read content -") - if f, err := doc.Dir.Open(n); err == nil { - if title, err = bufio.NewReader(f).ReadString('\n'); err == nil { - title = strings.TrimPrefix(title, "# ") + + // We have 3 forms of content: + // page -> we need to parse page.md to get its title name + // foo/index -> we need to parse foo/index.md to get its title name and parse its tocs + // alias -> we open bar to get its title name for the reverse lookup, but also adds the alias. + alias, p, found := strings.Cut(t, "<") + if found { + p = strings.TrimSuffix(p, ">") + } else { + p = alias + } + p = filepath.Join(root, p) + ".md" + + title, err := titleFromPage(dir, p) + if err != nil { + return nil, nil, nil, err + } + filesToTitle[p] = title + + chapterName := toCmdlineChapterName(title, parentChapterName) + chaptersToFiles[chapterName] = p + // chapterName is either the page title or the alias if set. + if found { + alias = toCmdlineChapterName(alias, parentChapterName) + chaptersToFiles[alias] = p + chapterName = alias + } + orderedChapters = append(orderedChapters, chapterName) + + // Look for any children index files and merge them into the parent one. + if strings.HasSuffix(p, "index.md") { + orderedChaptersChild, chaptersToFilesChild, filesToTitleChild, err := docStructure(dir, p, chapterName) + if err != nil { + return nil, nil, nil, err } - if err = f.Close(); err != nil { - log.Infof(stream.Context(), "Can't close documentation file: %v", err) + + orderedChapters = append(orderedChapters, orderedChaptersChild...) + for chapter, p := range chaptersToFilesChild { + chaptersToFiles[chapter] = p + } + for p, title := range filesToTitleChild { + filesToTitle[p] = title } } - content += fmt.Sprintf(" 1. [**%s**] %s\n", fileNameToDocumentChapter(n), title) } - if err := stream.Send(&adsys.StringResponse{ - Msg: content, - }); err != nil { - log.Warningf(stream.Context(), "couldn't send documentation to client: %v", err) + if s.Err() != nil { + return nil, nil, nil, fmt.Errorf("can't scan index file: %w", err) } - return nil + + return orderedChapters, chaptersToFiles, filesToTitle, err +} + +// titleFromPage extracts the title from a given markdown file. +func titleFromPage(dir embed.FS, path string) (string, error) { + f, err := dir.Open(path) + if err != nil { + return "", err + } + defer f.Close() + + s := bufio.NewScanner(f) + if !s.Scan() { + return "", fmt.Errorf("empty page") + } + + title := strings.TrimPrefix(strings.TrimSpace(s.Text()), "# ") + + if s.Err() != nil { + return "", fmt.Errorf("can't scan file: %w", s.Err()) + } + + return title, nil } -// fileNameToDocumentChapter strips prefix (before first dash) and suffix of documentation files. -func fileNameToDocumentChapter(name string) string { - parts := strings.SplitN(name, "-", 2) - if len(parts) > 1 { - name = parts[1] +// toCmdlineChapterName returns lowercase chapter name used for shell completion and user entry. +func toCmdlineChapterName(t, parentChapterName string) string { + if parentChapterName != "" { + t = filepath.Join(parentChapterName, t) } - return strings.TrimSuffix(name, ".md") + return strings.ToLower(strings.ReplaceAll(strings.TrimSpace(t), " ", "-")) } -// documentChapterToFileName returns the first file matching the name of a chapter. -func documentChapterToFileName(dir embed.FS, chapter string) (string, error) { - fs, err := dir.ReadDir(".") +func renderDocumentationPage(p string, filesToTitle map[string]string) (string, error) { + var out strings.Builder + + currentDir := filepath.Dir(p) + + f, err := docs.Dir.Open(p) if err != nil { - return "", fmt.Errorf(i18n.G("could not list documentation directory: %v"), err) + return "", fmt.Errorf(i18n.G("no file %q found in documentation"), p) } + defer f.Close() - // Sort all file names while they have their prefix - var names []string - for _, f := range fs { - names = append(names, f.Name()) - } - sort.Strings(names) + var inTocTree, shouldRenderTocTree bool + startToctree := "```{toctree}" + endToctree := "```" + + s := bufio.NewScanner(f) + for s.Scan() { + l := s.Text() + trimmedLine := strings.TrimSpace(l) + if trimmedLine == startToctree { + shouldRenderTocTree = true + inTocTree = true + continue + } else if trimmedLine == endToctree { + inTocTree = false + continue + } + + // Handle to tree content by replacing visible ones with a list of titles or aliases + if inTocTree { + if trimmedLine == ":hidden:" { + shouldRenderTocTree = false + } + if strings.HasPrefix(trimmedLine, ":") || !shouldRenderTocTree || trimmedLine == "" { + continue + } + + title, _, aliasFound := strings.Cut(trimmedLine, "<") + if !aliasFound { + p = filepath.Join(currentDir, title) + ".md" + title = filesToTitle[p] + } + + l = fmt.Sprintf(" * %s", title) + } + + // Strip grids + if strings.HasPrefix(l, "````") || strings.HasPrefix(l, "```{grid") { + continue + } + /* + ### [Explanation](explanation/index) -> ### Explanation + */ + // Replace image urls + if strings.HasPrefix(l, "![") { + l = imageURLToRTDURL(l) + } + + // Remove all remaining internal links for now as we can't bind them. + l = stripInternalLinks(l) - for _, n := range names { - if strings.EqualFold(fileNameToDocumentChapter(n), chapter) { - return n, nil + _, err := out.Write([]byte(l + "\n")) + if err != nil { + return "", err } } - // Try exact match, posfixing with .md if not found - if !strings.HasSuffix(chapter, ".md") { - chapter = fmt.Sprintf("%s.md", chapter) + if s.Err() != nil { + return "", fmt.Errorf("can't scan file: %w", s.Err()) } - if _, err := dir.Open(chapter); err == nil { - return chapter, nil + + return out.String(), nil +} + +var reURL = regexp.MustCompile(`\.\./images/(.+/)*`) + +// imageURLToRTDURL rewrites images links to match Read the Docs format. +func imageURLToRTDURL(imageLine string) string { + return reURL.ReplaceAllString(imageLine, docs.RTDRootURL+"/_images/") +} + +// Regular expression pattern to match [title](URL). +var reInternalLinksURL = regexp.MustCompile(`\[(.*?)\]\(.*?\)`) + +// stripInternalLinks strips the link part from URL. +func stripInternalLinks(line string) string { + if strings.Contains(line, "http") { + return line } - return "", fmt.Errorf(i18n.G("no file found matching chapter %q"), chapter) + return reInternalLinksURL.ReplaceAllString(line, "$1") }