1"""
2    salt.cli.api
3    ~~~~~~~~~~~~~
4
5    Salt's api cli parser.
6
7"""
8
9
10import logging
11
12import salt.client.netapi
13import salt.utils.files
14import salt.utils.parsers as parsers
15from salt.utils.verify import check_user, verify_log, verify_log_files
16
17log = logging.getLogger(__name__)
18
19
20class SaltAPI(parsers.SaltAPIParser):
21    """
22    The cli parser object used to fire up the salt api system.
23    """
24
25    def prepare(self):
26        """
27        Run the preparation sequence required to start a salt-api daemon.
28
29        If sub-classed, don't **ever** forget to run:
30
31            super(YourSubClass, self).prepare()
32        """
33        super().prepare()
34
35        try:
36            if self.config["verify_env"]:
37                logfile = self.options.api_logfile
38                if logfile is not None:
39                    # Logfile is not using Syslog, verify
40                    with salt.utils.files.set_umask(0o027):
41                        verify_log_files([logfile], self.config["user"])
42        except OSError as err:
43            log.exception("Failed to prepare salt environment")
44            self.shutdown(err.errno)
45
46        self.setup_logfile_logger()
47        verify_log(self.config)
48        log.info("Setting up the Salt API")
49        self.api = salt.client.netapi.NetapiClient(self.config)
50        self.daemonize_if_required()
51        self.set_pidfile()
52
53    def start(self):
54        """
55        Start the actual master.
56
57        If sub-classed, don't **ever** forget to run:
58
59            super(YourSubClass, self).start()
60
61        NOTE: Run any required code before calling `super()`.
62        """
63        super().start()
64        if check_user(self.config["user"]):
65            log.info("The salt-api is starting up")
66            self.api.run()
67
68    def shutdown(self, exitcode=0, exitmsg=None):
69        """
70        If sub-classed, run any shutdown operations on this method.
71        """
72        log.info("The salt-api is shutting down..")
73        msg = "The salt-api is shutdown. "
74        if exitmsg is not None:
75            exitmsg = msg + exitmsg
76        else:
77            exitmsg = msg.strip()
78        super().shutdown(exitcode, exitmsg)
79
80    def _handle_signals(self, signum, sigframe):
81        # escalate signal to the process manager processes
82        self.api.process_manager._handle_signals(signum, sigframe)
83        super()._handle_signals(signum, sigframe)
84